Verbindung zur Datenbank in eigenes Skript auslagern, dieses einbinden.
Wird insgesamt kürzer und richtiger.
Das war eigentlich absicht um das Ganze nicht zu verstrickt zu machen und man die einzelnen Dateien als Einsteiger "greifbar" und isoliert betrachten kann - ich hab sogar schon überlegt, das ganze ohne Affenformular und ohne redirects zu bauen, damit es noch leichter nachvollziehbar ist.
In der Praxis würde ich das ganz anders aufbauen - aber hier gehts um eine einfache Anleitung die entsprechende Grundlagen vermittelt und keine "do it perfectly"-Lösung.
1a)
bei der Gelegenheit auch die Kodierung setzen.
The character set must be set either at the server level, or with the API function mysqli_set_charset()
Hat in meinem Fall keine Rolle gespielt, darum hab' ich es ignoriert - ich bin hier bemüht das Ganze auf das Wesentliche zu beschränken.
Benutzernamen, Passwörter immer trimmen.
Beim Benutzer unter umständen ja, je nachdem welchen Zweck dieser hat. Wenn er ein Eindeutigkeitsmerkmal darstellt: ja, weil sonst sind Fakes mit Leerzeichen rundherum etwas einfach - da stimme ich zu. Aber diese Prüfung ist nicht Teil des Artikels, da hab' ich eh einen Absatz verfasst wo es um die Prüfung geht.
Bei Passwörtern ist das aber ein fataler Fehler: wenn jemand absichtlich sein Passwort mit einem Leerzeichen beginnt, ist das sehr unpraktisch.
Benutzername immer in Kleinbuchstaben;
Wozu? Sicher nicht :)
$query = 'INSERT INTO users (
username,
password
) VALUES (
"'.$mysqli->real_escape_string($_POST['f']['username']).'",
"'.$mysqli->real_escape_string($_POST['f']['password']).'"'
);
$mysqli->query($query);
müsste reichen, denn wenn der Spalteindex unique ist, dann schmeisst mysqli einen auswertbaren Fehler. Ist für mich perfekt genug.
Ja - funktionieren wird es, nur ist die Lösung sehr hölzern. Die Intention hinter der gezeigten Lösung ist, dass man hier auch komplexe Prüfungen machen kann, die man sonst mit den üblichen Feldeinstellungen nicht machen kann. Die Bedingungung im NOT-EXISTS-Zweig lässt sich nahezu beliebig anpassen.
Zudem ist es nie eine gute Lösung sich auf einen Fehler zu verlassen - es funktioniert zwar, aber "funktionieren" ist etwas anders :)
Kann ich Dir meine Variante schicken (tar.gz)? Die ist zwar noch nicht perfekt, auch mit dem ungeliebten mysql- statt mysqli - funktioniert aber schon prächtig.
Schmeiss mal auf meine Mail-Adresse.
Und nein. Ich benutze nicht crypt, sondern hash mit sha256 (liefert vertrauenserweckende, gegen openssl geprüfte, also in anderen Sprachen wiederholbare Ergebnisse - was mir wichtig ist) und einen Salt aus allen druckbaren ASCII-Zeichen mit einstellbarer Länge (default:32). Auch die Iterationen (default:50000) lege ich (oder der Anwender) fest.
SHA-256 ist defekt, viel zu schnell und führt kein key stretching durch - für Passwörter absolut ungeeignet. Ebenso gibt es kaum vernünftige Gründe auf crypt bzw. allgemein auf Standards zu verzichten.
Wenn in diesem beispiel bcrypt künftig nicht mehr ausreicht, muss einfach nur das Crypt-Schema umgestellt werden - alle alten Passwörter funktionieren dann trotzdem noch und alle neuen werden entsprechend stärker generiert. In deinem Fall musst du vermutlich einen Handstand machen. Das halte ich für nicht sinnvoll.