Hi!
ich habe mir mal ein Log-In-Script gesucht und versucht das an die Sachen anzupassen, die ich heute gelernt habe :-))
Hier mal das ganze Script, zu dem ich allerdings schon wieder Fragen habe :-((
Schlecht wäre es, wenn du keine Fragen hättest.
$verbindung = mysql_connect("localhost", "Benutzername" , "Passwort")
if(!isset($verbindung))
isset() ist nicht richtig, denn das gibt nur true zurück, wenn eine Variable gar nicht vorhanden ist oder ihr Inhalt NULL ist. Ein einfacher Vergleich reicht hier aber: if(!$verbindung) { ...
mysql_select_db("homepage")
if(!isset())
stattdessen:
if (!mysql_select_db("homepage"))
if($_POST["passwort"] != $_POST["passwort2"] OR $_POST["username"] == "" OR $_POST["passwort"] == "")
Wenn du es ganz richtig machen willst, müsstest du noch eine Prüfung auf Existenz einbauen, befor du auf das jeweilige Elememnt in $_POST zugreifst. In dem Fall mag das unwahrscheinlich aussehen, weil üblicherweise dein Formular zum Aufruf dieses auswertenden Codes führt und da alle Felder vorhanden sein sollten. Bei GET und einer per Hand manipulierbaren URL ist das schon eher möglich, dass Werte fehlen. Aber so gravierend länger wird es mit Vorhandensein-Prüfung auch wieder nicht, denn man kann statt isset() auch empty() nehmen und das kann man mit der Prüfung auf nicht ausgefüllte Felder kombinieren.
if(empty($_POST["passwort"]) or empty($_POST["passwort2"]) or empty($_POST["username"]) or $_POST["passwort"] != $_POST["passwort2"])
echo "Du musst alle Felder ausfüllen. <a href="eintragen.html">Zurück</a>";
Die Meldung passt aber nicht, wenn nur die Passwort-Eingaben nicht übereinstimmen. Diese Prüfung würde ich unabhängig von der Leer-Prüfung vornehmen.
$result = mysql_query("SELECT id FROM login WHERE username LIKE '" . mysql_real_escape_string($_POST["username"]) . "'");
$menge = mysql_num_rows($result);
if($menge == 0)
Kann man so machen, es ist aber effizienter - besonders bei großen Datenmengen - wenn man nicht alle Datensätze abfragt und sie durch mysql_num_rows() zählen lässt - denn dazu müssen sie erst zu PHP transportiert werden, was bei einem mysql_query() stets automatisch im Hintergrund passiert - sondern das Zählen im DBMS vornimmt (SELECT COUNT(*) ...) und nur das Ergebnis übertragen lässt, was man dann allerdings wie normale Abfragedaten auch erst fetchen muss. Insofern ist die mysql_num_rows()-Version kürzer.
Ich sollte die Strings sicherer machen durch "mysql_real_escape_string()" und auch darauf achten, dass ein Script nicht einfach abgebrochen wird, ohne dem Benutzer eine Alternative zu bieten. Das habe ich hier versucht.
Für den Anfang schon nicht schlecht. Allerdings ist das Sterbenlassen (mit exit oder die) nicht die feine englische Art, denn dabei entsteht üblicherweise ein unvollständiges Dokument im Browser. Hier hilft beispielsweise eine Umstellung der Verarbeitung auf das EVA-Prinzip: Eingabe-Verarbeitung-Ausgabe. Im E-Schritt sammelt man die Eingabedaten zusammen, was man bei PHP weniger braucht, sie sind ja schon in $_POST und $_GET enthalten. Aber eine Prüfung auf Vorhandensein kann man zum E-Teil zählen. Zum Verarbeiten der Daten zählen Prüfungen auf fachlichen Inhalt und das Lesen und Schreiben in Datenhaltungen. Auftretende Fehler und Ausgabedaten werden gesammelt. Im Ausgabeteil werden nun die zusammengesammelten Werte und/oder gegebenenfalls Fehlermeldungen ausgegeben. Zuerst der Beginn des HTML-Dokuments, am Ende der Abschluss und dazwischen die Werte oder Fehlermeldungen.
if(!isset($verbindung))
Muss ich hier ein "else" zwingend einfügen oder kann ich das Script einfach weiterlaufen lassen, wenn die Verbindung zur Datenbank geöffnet wurde?
Du brichst das Script ja ab. Anweisungen nach einem else-Block werden durch den Abbruch auch nicht mehr ausgeführt. Ein else wäre in dem Fall unnötig. Anders sähe die Sachlage aus, wenn du nach EVA strukturiertest.
Wenn ich es richtig verstanden habe, muss ich "mysql_real_escape_string()" nur verwenden, wenn ich php-Befehle verwende, die etwas mit SQL zu tun haben, deshalb habe ich den nachfolgenden if-Befehl nur angepasst, was die Variablen angeht.
Du musst es immer dann verwenden, wenn du Daten als String in ein SQL-Statement einfügen willst. Also immer dann, wenn im SQL-Statement etwas in '' oder "" eingefügt werden soll.
mysql_real_escape_string() sieht die Platzhalterzeichen % und _ nicht als besondere Zeichen an, die man escapen muss. Diese kommen also unverändert im SQL-String an.
$result = mysql_query("SELECT id FROM login WHERE username LIKE '" . mysql_real_escape_string($_POST["username"]) . "'");
$menge = mysql_num_rows($result);
>
> Ist es richtig, dass ich hier kein %-Zeichen eingetragen habe weil ich keinen Platzhalter brauche oder ist das ein Denkfehler und ich brauche das bei LIKE zwingend (den Teil habe ich immer noch nicht kapiert, dabei tüftle ich da schon den ganzen Tag rum!)
Dinge wie Benutzernamen sind eindeutige, einmalige Daten, die man in der Regel auf vollständige Übereinstimmung (maximal noch groß-/kleinschreibungsunabhängig) testet, also man eher mit = statt LIKE arbeitet.
> In der Beschreibung zum Kontextwechsel standen immer nur Beispiele mit SELECT, aber da es sich hier um einen Befehl bezüglich der Datenbank handelt und Benutzereingaben verwendet werden, habe ich hier das "mysql\_real\_escape\_string()" mit eingefügt.
> Ist das so korrekt?
Gilt für alle Arten von SQL-Statement gleichermaßen, also SELECT, INSERT, DELETE, UPDATE, ...
Lo!