poison: Daten bei mysql_connect verschlüsseln

Hallo,

nach viel Knobelei ist es endlich geschafft.
Mein Script funktioniert:

  
<?php  
$benutzername=$_POST['benutzername'];  
$passwort=$_POST['passwort'];  
  
  
if($passwort=="Harry Potter")  
{  
  
$verbindung = mysql_connect('localhost', 'Vesta', 'vesta');  
mysql_select_db("homepage");  
  
$abfrage = "SELECT bilderraetsel, galleonen FROM rustleoaks WHERE benutzername LIKE '$benutzername'";  
$ergebnis = mysql_query($abfrage);  
while($row = mysql_fetch_object($ergebnis))  
  
if($row->bilderraetsel == 0)  
{  
  
$aendern = "UPDATE rustleoaks Set  
bilderraetsel=1 WHERE benutzername LIKE '$benutzername'";  
$update = mysql_query($aendern);  
  
$aendern = "UPDATE rustleoaks Set  
galleonen=galleonen+3 WHERE benutzername LIKE '$benutzername'";  
$update = mysql_query($aendern);  
  
echo "Das ist korrekt";  
}  
else  
{  
echo "Du hast das Rätsel schon gemacht!";  
}  
}  
else  
{  
echo "Das ist nicht korrekt!";  
}  
?>  

Das ist mal nur die Rohform. Schönheitskorrekturen was die Ausgabe (echo) betrifft sowie die Sache mit der Verschlüsselung des Passwortes oder besser Lösungswortes (das Script ist ja für ein Rätsel) müssen noch gemacht werden.

Jetzt habe ich aber weitere Fragen dazu bzw. zu den Login-Scripten, die man im Netz findet.

1. Um die Datenbank zu öffnen, muss man ja immer den Servernamen, das Passwort und den Benutzernamen angeben. Auf meinem lokalen Server zum üben und in den vielen Beispielen, sind diese Daten für jeden ersichtlich. Wenn ich das ganze in meiner Homepage nun Online stelle, muss ich solche Eingaben ja aber verschlüsseln.

Wie genau mache ich das? Mit MD5?
Ich habe zu diesem Thema schon knapp zwei Stunden "gegoogelt" und habe nichts brauchbares gefunden. Vielleicht habe ich auch die falschen Suchkriterien eingegeben.

2. Wenn meine Besucher das Formular zum Lösen des Rätsels verwenden, sollen sie nicht noch einmal ihren Benutzernamen eingeben müssen. Das Script sollte mit dem Benutzernamen der Session arbeiten, d.h. die Abfrage der Variablen $benutzername sollte entfallen.

Muss ich dazu einfach $benutzername durch $_SESSION['benutzername'] ersetzen?

Wäre echt dankbar für eine weitere Erleuchtung.

Liebe Grüße
Poison

  1. Hallo,

    Wie genau mache ich das? Mit MD5?
    Ich habe zu diesem Thema schon knapp zwei Stunden "gegoogelt" und habe nichts brauchbares gefunden. Vielleicht habe ich auch die falschen Suchkriterien eingegeben.

    MD5 wird nach wie vor häufig zur Verschlüsselung von Passwörtern verwendet, ist aber nicht mehr zu 100% sicher, weil man theoretisch aus zwei verschiedenen Passwörtern denselben Hash rausbekommt, was sich widerrum zum Knacken des Passwortschutzes ausnutzen lässt.

    Guck Dir mal diesen Artikel an, dort wird AES als Verschlüsselung empfohlen.

    Viele Grüße,
    Jörg

    1. Hallo,

      MD5 wird nach wie vor häufig zur Verschlüsselung von Passwörtern verwendet,(...)

      kann man das wirklich eine "Verschlüsselung von Passwörtern" nennen? Schließlich handelt es sich um eine Hash-Funktion, die eine Art digitalen Fingerabdruck erzeugt. Der Inhalt wird dabei in einer komprimierten und möglichst eindeutigen Form wiedergegeben. Jedoch gehen Informationen verloren, sodass ein MD5-String nicht eindeutig ist. Ein entschlüsseln ist also nicht möglich. Kann man also überhaupt von einem verschlüsseln sprechen?

      Dann müsste das Bilden einer Quersumme doch auch eine Art der Verschlüsselung darstellen. ;-)

      Viele Grüße Novi

      --
      "(...) deshalb mag ich Binärtechnik. Da gibt es nur drei Zustände: High, Low und Kaputt." (Wau Holland)
  2. Wenn ich das ganze in meiner Homepage nun Online stelle, muss ich solche Eingaben ja aber verschlüsseln.

    Nein musst du nicht. Warum auch? Wer dein Script in die Hände kriegt, der kommt auch auf die DB. Wenn man nur mit verschlüsseltem Passwort drauf käme, dann könnte dieser jemand das auch mit deinem Script. Wenn das Script ein Passwort erst entschlüsseln müsste, könnte er es auch.

    Du musst den Server so absichern dass keiner an die Scripte kommt, dann ist schon alles dicht genug.

    1. Hi!

      Du musst den Server so absichern dass keiner an die Scripte kommt, dann ist schon alles dicht genug.

      Mitnichten ist dann alles dicht genug, denn neben dem wie üblich unsinnigen Umkopieren von POST-Werten am Anfang hat er auch noch - wie üblich - die Kontextwechsel-Problematik übersehen. Und dass er sich auch nicht darum kümmert, dass sein Script für Fehlerfälle robust genug ist, ist leider auch üblich.

      Lo!

      1. Hi dedlfix,

        Mitnichten ist dann alles dicht genug, denn neben dem wie üblich unsinnigen Umkopieren von POST-Werten am Anfang hat er auch noch - wie üblich - die Kontextwechsel-Problematik übersehen.

        Also:

        1. Ich bin kein "er", sondern eine "sie".
        Danke, dass man es Mädchen überhaupt nicht zutraut, sich für was anderes als Puppen zu interessieren. :-)))

        2. Da ich PHP-Neuling bin und echte Probleme mit dem Thema Kontextwechsel hatte, war ich frech und habe das meiste aus einem Tutorial kopiert und meinen Ideen angepasst. Zum Thema T_STRING Fehler hatte ich schon einen Tread geöffnet, leider aber keine Antwort bekommen, die mir wirklich weitergeholfen hätte. Ach ja, das mit den POST-Werten findest du in jedem Beispiel auf diversen Seiten, anhand dem du dich in PHP einarbeitest.

        3. Wie bei 2. schon bemerkt, bin ich Anfänger und immer offen für TIPPS. Also, was genau soll ich in mein Script noch einbringen? Welche Fehlerfälle sollte ich abdecken? Wenn schon gemeckert, dann bitte auch einen konkreten Verbesserungsvorschlag :-))

        Grüße
        Poison

        1. Hi!

          1. Ich bin kein "er", sondern eine "sie".
            Danke, dass man es Mädchen überhaupt nicht zutraut, sich für was anderes als Puppen zu interessieren. :-)))

          Spielt keine Rolle. Fehler bleiben Fehler, egal wer sie macht.

          1. Da ich PHP-Neuling bin und echte Probleme mit dem Thema Kontextwechsel hatte, war ich frech und habe das meiste aus einem Tutorial kopiert und meinen Ideen angepasst.

          Leider legen die Tutorials ihren Fokus mehr auf das Beibrigen von Funktionalitäten der Sprache, aber selten auf eine sichere und robuste Programmierung. Der Anfänger wird sich dadurch nicht bewusst, dass er/sie/es/egal da massive Sicherheitslücken in seine Scripte einbaut.

          Hast du den Artikel mittlerweile gelesen und verstanden, dass man beim Einfügen von Daten in Strings, die Code für ein bestimmtes System darstellen, diese Daten so notieren muss, dass sie Daten bleiben und nicht durch nicht beachtete Zeichen zum Code werden?

          Zum Thema T_STRING Fehler hatte ich schon einen Tread geöffnet, leider aber keine Antwort bekommen, die mir wirklich weitergeholfen hätte.

          Welcher Thread war das denn?

          Ach ja, das mit den POST-Werten findest du in jedem Beispiel auf diversen Seiten, anhand dem du dich in PHP einarbeitest.

          Ja, das macht es auch nicht besser. Für viele scheinen $_POST und $_GET irgendwelche Monster zu sein, aus denen man möglichst schnell seine Daten rausholen muss, da es sonst Unglück gäbe. Dieses Vorgehen ist jedoch ein Überbleibsel aus der Zeit des Übergangs von register_globals=on zu off. Bei on wurden die $_GET/$_POST-Werte von PHP als einfache Variablen zur Verfügung gestellt und alle schrieben ihre Scripte so, dass sie auf diese Variablen zugriffen. Die einfachste Abhilfe war bei off, faulerweise die Scripte so zu lassen und nur das Umkopieren an den Anfang zu stellen. Und so verbreitete sich eine Unsitte, die ncihts weiter bringt als zusätzliche Variablen, bei denen man sich merken muss, wie sie entstanden sind und die ihre Herkunft verharmlosen. Letzerer Punkt sollte aber weniger von Belang sein, denn der Kontextwechsel muss für alle Daten gleichsam beachtet werden, und nicht etwa nur in einer besonderen Form für Eingabewerte.

          Also, was genau soll ich in mein Script noch einbringen? Welche Fehlerfälle sollte ich abdecken?

          Ein DBMS ist ein System, das in der Regel auf einem separaten Server läuft, dessen mögliche Ausfälle nicht synchron sind zu denen des Webservers. Deshalb kann zum Beispiel ein Verbindungsaufbau scheitern. In solchen Fällen gibt es keine Fehlermeldung von PHP sondern die mysql(i)-Funktionen geben über den Rückgabewert (=false) bekannt, wenn etwas nicht funktioniert hat. In einem solchen Fall ist es sinnlos fortzufahren, also ob nichts passiert wäre, und munter und froh weitere Befehle gegen das nicht ansprechbare DBMS abzufeuern. Abgesehen davon, dass es nun auch seitens PHP Folgefehlermeldungen hagelt, denn "false" ist keine Ressourcenkennung, die die mysql(i)-Funktionen erwarten. Also: Werte die Rückgabewerte der verwendeten Funktionen aus. Das betrifft jedes Gebiet, nicht nur MySQL. Schau dazu im PHP-Handbuch nach, was die von dir verwendeten Funktionen im Fehlerfall zurückliefern, wie man das gegebenenfalls von positiven Werten unterscheiden kann (Beispiel strpos(): false beim Nichtfinden vs. Integer-0 beim Fund am Stringanfang), und baue Fallunterscheidungen ein.

          if ($connection = mysql_connect(...)) {
              // weiter im Text
            } else {
              // Alternativprogramm
            }

          Das muss man gegebenenfalls mehrfach verschachteln, je nachdem, wieviele Funktionen mit möglichem Fehler-Rückgabewert man verwendet. Zum Alternativprogramm muss man sich vor Augen halten, für wen man das Script überhaupt geschrieben hat. Einen konkretern Fehlermeldungstext auszugeben, bringt dem Anwender nämlich überhaupt nichts. Im Gegenteil könnten nun dir weniger wohl Gesonnene aus den konkreten veröffentlichen Details gezieltere Angriffe starten. Der normale Anwender kann die Ursache des Fehlers nicht beheben und es ist ihm auch egal, wenn da was im Hintergrund nicht richtig gelaufen ist. Er will einfach nur sein Ziel erreichen. Bei einem Verkaufsvorgang ist das auch für den Betreiber der Website wichtig, dem Kunden nun eine Alternative zu bieten, so dass die Bestellung doch noch abgesendet werden kann. In dem Fall könnte man die Bestelldaten vielleicht per E-Mail versenden statt sie im DBMS einzutragen (ganz abgesehen davon, dass schon der Katalog bei DBMS-Problemen nicht erreichbar sein wird).

          Mit dem gezielten Beachten von möglichen Fehlerzuständen macht man sein Programm "nur" robust, die Kontextwechsel nicht zu beachten bringt mehr oder weniger schwere Sicherheitslücken in das eigenen System (z.B. Datenbank) und das des Besuchers, wenn jemandem Javascript einschleusen kann, das in Richtung des Besuchers geschickt wird.

          Lo!

          1. Hi!

            Zum Thema T_STRING Fehler hatte ich schon einen Tread geöffnet, leider aber keine Antwort bekommen, die mir wirklich weitergeholfen hätte.
            Welcher Thread war das denn?

            Ach, der da. Was war denn daran nicht zielführend? Du musst natürlich auch sagen, wenn dir eine Antwort nicht einleuchtend erscheint oder du den Eindruck hast, sie hilft dir nicht weiter. Du hattest da einen String nicht wieder geschlossen. Anhand der Syntaxhervorhebung sollte die Stelle recht einfach zu finden sein. Man muss nur genau beobachten und die Stelle finden, bei der ein Farbwechsel fehlt.

            Lo!

          2. Hi!

            danke für deine Rückmeldung.

            Hast du den Artikel mittlerweile gelesen und verstanden, dass man beim Einfügen von Daten in Strings,

            die Code für ein bestimmtes System darstellen, diese Daten so notieren muss, dass sie Daten bleiben und
            nicht durch nicht beachtete Zeichen zum Code werden?

            Ja. ich habe den Artikel gelesen, sogar mehrmals, weil ich anfangs nicht richtig begriffen habe, worauf der Schreiber hinaus wollte.
            Verstanden habe ich folgendes:

            Wenn ich einen String wie diesen hier habe (ist aus dem Artikel kopiert)

              
            "SELECT feldliste FROM tabelle WHERE feld='$variable'";  
            
            

            muss ich den String zwingend mit " beginnen und mit "; beenden. Außerdem muss ich darauf achten, die Werte, die ich in dem String eingebe ( z.B. $variable) in '' zu setzen. Das habe ich bei mir auch soweit berücksichtigt.

              
            $aendern = "UPDATE rustleoaks Set  
            bilderraetsel=1 WHERE benutzername LIKE '$benutzername'";  
            
            

            Den Wert 1 habe ich nicht mit Hochkommas versehen, da es einen T_String Fehler verursacht. Irgendwo habe ich gelesen, Zahlen dürfen nicht in Hochkommas gesetzt werden.

            Um zu verhindern, dass mir jemand einen Befehl über das Formular unterschiebt, sollte ich jedoch den String nichtso stehen lassen, sondern den Befehl mysql_real_escape_string() mit einfügen. Weiterer Vorteil, ich muss nicht darauf achten, ob ich etwas mit Backslash \ maskieren muss. Dann würde mein Befehl so aussehen:

            [code lang=php]
            $aendern = "UPDATE rustleoaks Set bilderraetsel='" . mysql_real_escape_string(1) . "' WHERE benutzername
            LIKE '" . mysql_real_escape_string($_POST['benutzername']) . "'";

            Da es sich bei der Zahl 1 um einen von mir vorgegebenen Wert und nicht um einen Wert aus Benutzereingaben handelt, kann ich den Befehl so verwenden (benutze mySQL). Die Besonderheit bei der LIKE-Angabe habe ich noch nicht ganz kapiert. Darf ich hier den Befehl mysql_real_escape_string() gar nicht verwenden, oder wird es nur wegen der eventuellen Verwendung von sprintf und dem %-Zeichen besonders aufgeführt?

            Oder ist das alles auch wieder falsch?

            Liebe Grüße
            Poison

            1. Moin!

              Ja. ich habe den Artikel gelesen, sogar mehrmals, weil ich anfangs nicht richtig begriffen habe, worauf der Schreiber hinaus wollte.

              Hehe, du diskutierst gerade mit dem Schreiber. ;)

              Verstanden habe ich folgendes:

              Wenn ich einen String wie diesen hier habe (ist aus dem Artikel kopiert)

              "SELECT feldliste FROM tabelle WHERE feld='$variable'";

              
              >   
              > muss ich den String zwingend mit " beginnen und mit "; beenden. Außerdem muss ich darauf achten, die Werte, die ich in dem String eingebe ( z.B. $variable) in '' zu setzen. Das habe ich bei mir auch soweit berücksichtigt.  
                
              Darauf will der Artikel gar nicht hinaus!  
                
              In PHP musst du einen String, den du mit doppelten Anführungszeichen " beginnst, auch mit diesen wieder beenden.  
                
              Genauso gilt die Vorschrift, wenn du den String mit einfachen Anführungszeichen ' beginnst.  
                
              Das Semikolon dahinter hat eine vollkommen andere Aufgabe - es trennt die einzelnen Befehle voneinander, hat mit dem String aber gar nichts zu tun.  
                
              Das einbauen von Variablen in den String unterliegt erstmal auch "nur" den Vorschriften von PHP. Variablen werden nur "ausgewertet", d.h. ihr Inhalt in den String integriert, wenn der String von doppelten Anführungszeichen umschlossen ist.  
                
              Eine Variable in einem String benötigt aus PHP-Sicht aber keinerlei besonderen Zeichen drumherum. Das ist eine Anforderung, die sich daraus ergibt, dass du in diesem String ein MySQL-Kommando herstellst.  
                
              Und genau darum dreht sich der Artikel: Wie kriegt man den Inhalt von Variablen beispielsweise sicher in einen SQL-Befehl integriert?  
                
              Und das steht im Abschnitt "Verhindernde Maßnahmen", den du anscheinend noch nicht gelesen hast.  
                
              
              > ~~~php
                
              
              > $aendern = "UPDATE rustleoaks Set  
              > bilderraetsel=1 WHERE benutzername LIKE '$benutzername'";  
              > 
              
              

              Den Wert 1 habe ich nicht mit Hochkommas versehen, da es einen T_String Fehler verursacht. Irgendwo habe ich gelesen, Zahlen dürfen nicht in Hochkommas gesetzt werden.

              Der T_STRING-Fehler kommt von PHP. Er zeigt dir, dass du mit PHP einen Fehler gemacht hast. Es stimmt also irgendwas mit der PHP-Syntax nicht.

              Das hat aber keine Bedeutung für das SQL, was du hier zusammenbaust. Der SQL-String, den die Datenbank ausführen soll, hat seinerseits eine Syntax, die beim Zusammenbauen natürlich auch zu beachten ist.

              Für MySQL gilt: Zahlen KANN man ohne Anführungszeichen in den SQL-String schreiben, man KANN sie aber auch hinzufügen - das stört nicht, macht es aber einfacher, wenn Zahlen aus Variablen kommen und gesichert in den SQL-String geschrieben werden sollen.

              Um zu verhindern, dass mir jemand einen Befehl über das Formular unterschiebt, sollte ich jedoch den String nichtso stehen lassen, sondern den Befehl mysql_real_escape_string() mit einfügen. Weiterer Vorteil, ich muss nicht darauf achten, ob ich etwas mit Backslash \ maskieren muss. Dann würde mein Befehl so aussehen:

              $aendern = "UPDATE rustleoaks Set bilderraetsel='" . mysql_real_escape_string(1) . "' WHERE benutzername
              LIKE '" . mysql_real_escape_string($_POST['benutzername']) . "'";

              Aha, den Abschnitt hast du also doch gelesen... :)

              Da es sich bei der Zahl 1 um einen von mir vorgegebenen Wert und nicht um einen Wert aus Benutzereingaben handelt, kann ich den Befehl so verwenden (benutze mySQL).

              Für alles, was fest im String drinsteht und nicht aus Variablen kommt, brauchst du mysql_real_escape_string() nicht anwenden. Die feste Zahl "1" darf also direkt im SQL auftauchen.

              Die Besonderheit bei der LIKE-Angabe habe ich noch nicht ganz kapiert. Darf ich hier den Befehl mysql_real_escape_string() gar nicht verwenden, oder wird es nur wegen der eventuellen Verwendung von sprintf und dem %-Zeichen besonders aufgeführt?

              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.

              Wenn du jetzt eine Benutzereingabe für eine Wildcard-Suche anwendest, wäre die erste Überlegung:

              In SQL: Suche alles, was mit XYZ anfängt - und XYZ ist die Benutzereingabe.
              [code lang=sql]SELECT ... FROM ... WHERE feld LIKE 'XYZ%'

                
              In PHP: Bastel die Benutzereingabe in den String - aber bitte escapen.  
              ~~~php
              $sql = "SELECT ... FROM ... WHERE feld LIKE '".mysql_real_escape_string($searchFor)."%'",  
              
              

              Benutzereingabe lautet: % (der will halt alles suchen, was mit einem Prozentzeichen beginnt.

              Resultierendes SQL:
              SELECT ... FROM ... WHERE feld LIKE '%%'

              Wirkung: Es wird nach allem gesucht, was in der Datenbank steht - LIKE '%%' filtert nichts, sondern findet alle Einträge.

              Resultat: Es wird nicht nach dem Prozentzeichen gesucht, sondern alles gefunden. Das ist nicht, was der Benutzer wollte.

              Korrekt wäre folgender SQL-String gewesen:
              SELECT ... FROM ... WHERE feld LIKE '\%%'

              Das würde nach allem suchen, was mit einem Prozentzeichen anfängt.

              Da die MySQL-Extensions in PHP für diesen Sonderfall keine eigene Funktion anbieten, um diese Such-Platzhalter zu escapen, muss man sich das halt selbst bauen.

              Die Anwendung von sprintf() an der Stelle ist nur eine Erleichterung für das Zusammensetzen des SQL-Strings. Die Vorlage des Strings steht in einem Rutsch für sich allein, und enthält an den entsprechenden Stellen Platzhalter (%s für "String"). Dahinter kommen die weiteren Parameter von sprintf, die von vorne nach hinten für jeden Platzhalter den einzufügenden Wert enthalten.

              Das macht die Sache durchaus übersichtlicher, man muss es aber nicht so handhaben.

              - Sven Rautenberg

              1. 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 :-((

                  
                <?php  
                $verbindung = mysql_connect("localhost", "Benutzername" , "Passwort")  
                  
                if(!isset($verbindung))  
                {  
                echo "Leider ist ein Fehler bei der Registrierung aufgetreten.  
                echo  Bitte sende mir zur Registrierung eine E-Mail:  
                echo  <a href="mailto:mail@potionmaster.de">mail@potionmaster.de</a>"  
                exit;  
                }  
                  
                mysql_select_db("homepage")  
                  
                if(!isset())  
                {  
                echo "Leider ist ein Fehler bei der Registrierung aufgetreten.  
                echo  Bitte sende mir zur Registrierung eine E-Mail:  
                echo  <a href="mailto:mail@potionmaster.de">mail@potionmaster.de</a>"  
                exit;  
                }  
                  
                if($_POST["passwort"] != $_POST["passwort2"] OR $_POST["username"] == "" OR $_POST["passwort"] == "")  
                {  
                echo "Du musst alle Felder ausfüllen. <a href=\"eintragen.html\">Zurück</a>";  
                exit;  
                }  
                  
                $passwort = md5($_POST["passwort"]);  
                  
                $result = mysql_query("SELECT id FROM login WHERE username LIKE '" . mysql_real_escape_string($_POST["username"]) . "'");  
                $menge = mysql_num_rows($result);  
                  
                if($menge == 0)  
                    {  
                    $eintrag = "INSERT INTO login (username, passwort) VALUES ('" . mysql_real_escape_string($_POST["username"]) . "', '" . mysql_real_escape_string($passwort) . "')";  
                    $eintragen = mysql_query($eintrag);  
                  
                    if($eintragen == true)  
                        {  
                        echo "Hallo <b>$_POST["username"]</b>, Du hast Dich erfolgreich registriert. <a href=\"anmelden.html\">Anmelden</a>";  
                        }  
                    else  
                        {  
                        echo "Registrierung ist fehlgeschlagen.  
                        echo  Sollte Deine Registrierung nochmals fehlschlagen, sende mir bitte eine E-Mail:  
                        echo <br>  
                        echo <br>  
                        echo <a href=\"eintragen.html\">Zurück</a>";  
                        }  
                  
                }  
                else  
                {  
                echo "Der Benutzername ist schon vergeben. Du musst einen anderen wählen.  
                echo  <a href=\"eintragen.html\">Zurück</a>";  
                }  
                ?>  
                
                

                OK.
                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.

                1. Frage

                  
                if(!isset($verbindung))  
                {  
                echo "Leider ist ein Fehler bei der Registrierung aufgetreten.  
                echo  Bitte sende mir zur Registrierung eine E-Mail:  
                echo  <a href="mailto:mail@potionmaster.de">mail@potionmaster.de</a>"  
                exit;  
                }  
                
                

                Muss ich hier ein "else" zwingend einfügen oder kann ich das Script einfach weiterlaufen lassen, wenn die Verbindung zur Datenbank geöffnet wurde?

                2. Frage

                  
                if(!isset(???))  
                {  
                echo "Leider ist ein Fehler bei der Registrierung aufgetreten.  
                echo  Bitte sende mir zur Registrierung eine E-Mail:  
                echo  <a href="mailto:mail@potionmaster.de">mail@potionmaster.de</a>"  
                exit;  
                }  
                
                

                Mit welchen Wert kann ich den if-Befehl füllen, sollte die Datenbank nicht ausgewählt werden konnte? Kann ich hier überhaupt einen if-Befehl verwenden, oder sollte ich lieber "or die" benützen?

                3. Frage
                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.

                4. Frage

                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.

                Wenn du jetzt eine Benutzereingabe für eine Wildcard-Suche anwendest, wäre die erste Überlegung:

                In SQL: Suche alles, was mit XYZ anfängt - und XYZ ist die Benutzereingabe.
                SELECT ... FROM ... WHERE feld LIKE 'XYZ%'

                In PHP: Bastel die Benutzereingabe in den String - aber bitte escapen.

                $sql = "SELECT ... FROM ... WHERE feld LIKE '".mysql_real_escape_string($searchFor)."%'",

                
                >   
                > Benutzereingabe lautet: % (der will halt alles suchen, was mit einem Prozentzeichen beginnt.  
                >   
                > Resultierendes SQL:  
                > `SELECT ... FROM ... WHERE feld LIKE '%%'`{:.language-sql}  
                >   
                > Wirkung: Es wird nach allem gesucht, was in der Datenbank steht - LIKE '%%' filtert nichts, sondern findet alle Einträge.  
                >   
                > Resultat: Es wird nicht nach dem Prozentzeichen gesucht, sondern alles gefunden. Das ist nicht, was der Benutzer wollte.  
                >   
                > Korrekt wäre folgender SQL-String gewesen:  
                > `SELECT ... FROM ... WHERE feld LIKE '\%%'`{:.language-sql}  
                >   
                > Das würde nach allem suchen, was mit einem Prozentzeichen anfängt.  
                >   
                > Da die MySQL-Extensions in PHP für diesen Sonderfall keine eigene Funktion anbieten, um diese Such-Platzhalter zu escapen, muss man sich das halt selbst bauen.  
                >   
                > Die Anwendung von sprintf() an der Stelle ist nur eine Erleichterung für das Zusammensetzen des SQL-Strings. Die Vorlage des Strings steht in einem Rutsch für sich allein, und enthält an den entsprechenden Stellen Platzhalter (%s für "String"). Dahinter kommen die weiteren Parameter von sprintf, die von vorne nach hinten für jeden Platzhalter den einzufügenden Wert enthalten.  
                >   
                  
                Mein Code:  
                ~~~php
                  
                $passwort = md5($_POST["passwort"]);  
                  
                $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!)

                5. Frage

                  
                $eintrag = "INSERT INTO login (username, passwort) VALUES ('" . mysql_real_escape_string($_POST["username"]) . "', '" . mysql_real_escape_string($passwort) . "')";  
                    $eintragen = mysql_query($eintrag);  
                
                

                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?

                Würde mich freuen, wenn ihr mir ein Feedback geben könntet. Bin auch offen für Änderungen am Script. Will es endlich richtig machen.

                Liebe Grüße
                Poison

                1. 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!
                  
                  1. Hi,

                    ich habe das Script nochmals überarbeitet und versucht alles, was du gestern noch als Verbesserung bzw. Korrektur angeführt hast, mit aufzunehmen/abzuändern.

                      
                    <?php  
                      
                    if(empty($_POST["passwort"]) or empty($_POST["passwort2"]) or empty($_POST["username"] or empty($_POST["email"])  
                    {  
                    echo "Du hast leider nicht alle Felder ausgefüllt. <a href=\"eintragen.html\">Zurück</a>";  
                    }  
                    else  
                    {  
                      
                      
                    //Alternative  
                      
                    if(empty($_POST["passwort"])  
                    {  
                    echo "Du hast leider kein Passwort angegeben. <a href=\"eintragen.html\">Zurück</a>";  
                    }  
                      
                    else if(empty($_POST["passwort2"])  
                    {  
                    echo "Du hast leider vergessen Dein Passwort erneut einzugeben. <a href=\"eintragen.html\">Zurück</a>";  
                    }  
                      
                    else if(empty($_POST["username"])  
                    {  
                    echo "Du hast leider vergessen Deinen Benutzernamen anzugeben. <a href=\"eintragen.html\">Zurück</a>";  
                    }  
                      
                    else if(empty($_POST["email"])  
                    {  
                    echo "Du hast leider vergessen Deine E-Mail-Adresse anzugeben. <a href=\"eintragen.html\">Zurück</a>";  
                    }  
                    else  
                    {  
                      
                    //Alternative Ende  
                      
                      
                      
                    if($_POST["passwort"] != $_POST["passwort2"])  
                    {  
                    echo "Deine Passwörter sind leider nicht identisch. <a href=\"eintragen.html\">Zurück</a>";  
                    }  
                    else  
                    {  
                      
                      
                    $verbindung = mysql_connect("localhost", "Benutzername" , "Passwort")  
                      
                    if(!$verbindung)  
                    {  
                    echo "Leider ist ein Fehler bei der Registrierung aufgetreten.  
                    echo  Bitte sende mir zur Registrierung eine E-Mail:  
                    echo  <a href="mailto:mail@potionmaster.de">mail@potionmaster.de</a>";  
                    }  
                    else  
                    {  
                      
                      
                    mysql_select_db("homepage")  
                      
                      
                    if(!mysql_select_db("homepage"))  
                    {  
                    echo "Leider ist ein Fehler bei der Registrierung aufgetreten.  
                    echo  Bitte sende mir zur Registrierung eine E-Mail:  
                    echo  <a href="mailto:mail@potionmaster.de">mail@potionmaster.de</a>";  
                    }  
                    else  
                    }  
                      
                      
                    $passwort = md5($_POST["passwort"]);  
                      
                    $result = mysql_query("SELECT id FROM login WHERE username= '" . mysql_real_escape_string($_POST["username"]) . "'");  
                    $menge = mysql_num_rows($result);  
                      
                      
                    //Alternative  
                      
                    $result = mysql_query("SELECT COUNT ('id') FROM login WHERE username= '" . mysql_real_escape_string($_POST["username"]) . "'");  
                    $menge = mysql_fetch_row($result);  
                      
                    // Alternative Ende  
                      
                      
                      
                    if($menge == 0)  
                    {  
                    $eintrag = "INSERT INTO login (username, passwort, email) VALUES ('" . mysql_real_escape_string($_POST["username"]) . "', '" . mysql_real_escape_string($passwort) . "', '" . mysql_real_escape_string($_POST["email"]) . "')";  
                    $eintragen = mysql_query($eintrag);  
                    }  
                      
                      
                    if($eintragen == true)  
                    {  
                    echo "Hallo <b>$_POST["username"]</b>, Du hast Dich erfolgreich registriert. <a href=\"anmelden.html\">Anmelden</a>";  
                    }  
                    else  
                    {  
                    echo "Deine Registrierung ist leider fehlgeschlagen.  
                    echo Sollte Deine Registrierung nochmals fehlschlagen, sende mir bitte eine E-Mail:  
                    echo <a href="mailto:mail@potionmaster.de">mail@potionmaster.de</a>  
                    echo <br>  
                    echo <br>  
                    echo <a href=\"eintragen.html\">Zurück</a>";  
                    }  
                      
                    }  
                    else  
                    {  
                    echo "Der Benutzername ist schon vergeben. Du musst einen anderen wählen.  
                    echo  <a href=\"eintragen.html\">Zurück</a>";  
                    }  
                      
                    //schließen der noch offenen "else" Anweisungen  
                      
                    }  
                    }  
                    }  
                    }  
                      
                    mysql_close ($verbindung);  
                    ?>  
                    
                    

                    Ich habe das isset() durch deine Vorgaben ersetzt. Außerdem habe ich nun die Leer-Prüfung von der Inhalt-Prüfung getrennt und an den Anfang des Scripts gestellt. Weiß nicht, ob das einen Unterschied macht, aber es erschien mir irgendwie sinnvoller. Da meine Besucher beim registrieren Ihre Mail-Adresse angeben müssen, habe ich das auch noch eingefügt.

                    Könnte ich die Prüfung der Mail-Adresse auf diese Weise machen?

                      
                    if(check_email($email))  
                    {  
                    $nonascii      = "\x80-\xff"; # Non-ASCII-Chars are not allowed  
                      
                    $nqtext        = "[^\\\\$nonascii\015\012\"]";  
                    $qchar         = "\\\\[^$nonascii]";  
                      
                    $protocol      = '(?:mailto:)';  
                      
                    $normuser      = '[a-zA-Z0-9][a-zA-Z0-9_.-]*';  
                    $quotedstring  = "\"(?:$nqtext|$qchar)+\"";  
                    $user_part     = "(?:$normuser|$quotedstring)";  
                      
                    $dom_mainpart  = '[a-zA-Z0-9][a-zA-Z0-9._-]*\\.';  
                    $dom_subpart   = '(?:[a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*';  
                    $dom_tldpart   = '[a-zA-Z]{2,5}';  
                    $domain_part   = "$dom_subpart$dom_mainpart$dom_tldpart";  
                      
                    $regex         = "$protocol?$user_part\@$domain_part";  
                      
                    return preg_match("/^$regex$/",$email);  
                    }  
                    else  
                    {  
                    echo "Du musst eine korrekt E-Mail-Adresse angeben.  
                    echo <a href=\"eintragen.html\">Zurück</a>";  
                    
                    

                    Sollte ich hier noch ein Beispiel angeben, damit der Besucher weiß, was ich mit korrekter E-Mail-Adresse meine?

                    Ich habe Alternativen eingefügt, wie man die Abfragen meinem Verständnis nach noch gestalten könnte. Allerdings weiß ich nicht, ob sie so richtig sind. Für die SELECT Abfrage mit COUNT(*) habe ich über Google keine Beispiele gefunden, an denen ich mich orientieren konnte.

                    Ist die Eingabe der Variablen $passwort bei dem Befehl INSERT eigentlich korrekt? Bis gestern abend war ich felsenfest davon überzeugt, da ja einige Zeilen vorher dies hier kommt:

                      
                    $passwort = md5($_POST["passwort"]);  
                    
                    

                    Mittlerweile habe ich allerdings das Gefühl, trotz ständigem Lesens, Nachschlagens usw. habe ich absolut keinen Schimmer von PHP. Bin für weitere TIPPs und Anregungen sehr dankbar.

                    Liebe Grüße
                    Poison

                    1. Hallo

                      ich habe das Script nochmals überarbeitet und versucht alles, was du gestern noch als Verbesserung bzw. Korrektur angeführt hast, mit aufzunehmen/abzuändern.

                      <?php

                      if(empty($_POST["passwort"]) or empty($_POST["passwort2"]) or empty($_POST["username"] or empty($_POST["email"])
                      {
                      echo "Du hast leider nicht alle Felder richtig ausgefüllt. <a href="eintragen.html">Zurück</a>";
                      }
                      else
                      {
                      // ...
                      }

                        
                      Abgesehen davon, dass die Prüfung auch die Gleichheit von `$_POST["passwort"]`{:.language-php} und `$_POST["passwort2"]`{:.language-php} enthalten sollte, ist es besser, an der Stelle nichts (per `echo`{:.language-php}) auszugeben sondern die Meldung in eine Variable zu schreiben. Einerseits folgt das dem schon von dedlfix mehrfach erwähnten und beschriebenen EVA-Prinzip, nachdem die Ausgabe allen Textes erst am Schluss erfolgt, andererseits müsstest du, so, wie du es tust, die Verarbeitung mitten im HTML-Quelltext erfolgen lassen um die Fehlermeldung im HTMl-Dokument zu haben, was (im Quelltext) nicht gerade übersichtlich ist.  
                        
                      Besser wäre also  
                        
                      ~~~php
                        
                      <?php  
                        
                      if(empty($_POST["passwort"]) or empty($_POST["passwort2"]) or empty($_POST["username"] or empty($_POST["email"])  
                      {  
                      $error = "Du hast leider nicht alle Felder ausgefüllt. <a href=\"eintragen.html\">Zurück</a>";  
                      } else {  
                      // Alle Felder ausgefüllt, weitere Verarbeitung  
                      // Daten für die Ausgabe werden samt HTML-Schnipseln in $output geschrieben.  
                      }  
                      ?>  
                      [code lang=html]  
                      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
                      <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">  
                      <head>  
                      <meta http-equiv="content-type" content="text/html; charset=UTF-8" />  
                      <title><?php echo $document['title']; ?></title>  
                      </head>  
                      <body>  
                      [code lang=php]<?php  
                      if (!empty($error))  
                      {  
                      echo '<div class="error"><p>'.$error.'</p></div>';  
                      } else {  
                      echo $output;  
                      }  
                      ?>
                      

                      </body>
                      </html>[/code][/code]

                      Ich habe das isset() durch deine Vorgaben ersetzt. Außerdem habe ich nun die Leer-Prüfung von der Inhalt-Prüfung getrennt und an den Anfang des Scripts gestellt. Weiß nicht, ob das einen Unterschied macht, aber es erschien mir irgendwie sinnvoller.

                      Ob die Daten falsch oder nicht ausgefüllt und übergeben werden, ist *für das Skript* "uninteressant". In beiden Fällen muss die Verarbeitung abgebrochen werden. Es ist aber dann sinnvoll, wenn du dem Benutzer für beide Fälle unterschiedliche Meldungen präsentieren willst. Für ihn ist es im Normalfall durchaus wichtig, zu wissen, ob er vergessen hat, ein Pflichtfeld auszufüllen oder ob er ein bestimmtes Feld falsch ausgefüllt hat.

                      Ich habe Alternativen eingefügt, wie man die Abfragen meinem Verständnis nach noch gestalten könnte. Allerdings weiß ich nicht, ob sie so richtig sind. Für die SELECT Abfrage mit COUNT(*) habe ich über Google keine Beispiele gefunden, an denen ich mich orientieren konnte.

                      Das Archiv dieses Forums gibt einiges her, wobei ich die Qualität der einzelnen Fundstellen nicht geprüft habe.

                      Ist die Eingabe der Variablen $passwort bei dem Befehl INSERT eigentlich korrekt? Bis gestern abend war ich felsenfest davon überzeugt, da ja einige Zeilen vorher dies hier kommt:

                      $passwort = md5($_POST["passwort"]);

                        
                      Mit md5 wird ein [Hashwert](http://de.wikipedia.org/wiki/Hashwert) eines Strings (oder auch einer Datei) erzeugt. Der soll pro String/Datei jeweils eindeutig sein. Es gibt mehrere Methoden/Funktionen, um Hashwerte zu errechnen, unter anderem auch MD5.  
                        
                      Der Vorteil im konkreten Fall ist, dass das Passwort \*nicht im Klartext\* in der Datenbank steht. \*Falls\* es dazu kommt, dass ein Unbefugter Zugriff auf die Datenbank bekommt, liegen ihm somit die Passwörter nicht im Klartext vor.  
                        
                      Beachte: Bei späteren Logins wird das nun eingegebene Passwort gegen seinen hinterlegten MD5-Wert geprüft. Dazu muss es ebenfalls mit md5() behandelt werden, damit beide Werte (die momentane Eingabe und der bei der Registrierung gespeicherte Wert) zueinander passen.  
                        
                      Tschö, Auge  
                      
                      -- 
                      Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.  
                      Terry Pratchett, "Wachen! Wachen!"  
                        
                      [Veranstaltungsdatenbank Vdb 0.3](http://termindbase.auge8472.de/)
                      
                      1. Hi,

                        ich habe jetzt das Script erneut geändert und bekomme schon gleich in Zeile 4 folgenden Fehler:

                        Parse error: syntax error, unexpected '{' on line 4

                        hier der Code dazu:

                          
                        if(empty($_POST["passwort"]) OR empty($_POST["passwort2"]) OR empty($_POST["username"]) OR empty($_POST["email"])  
                        {  
                        $error = "Du hast leider nicht alle Felder ausgefüllt. <a href=\"eintragen.html\">Zurück</a>";  
                        }  
                        else  
                        {  
                        // Alle Felder ausgefüllt, weitere Verarbeitung  
                        // Daten für die Ausgabe werden samt HTML-Schnipseln in $output geschrieben.  
                        }  
                        
                        

                        Ich verstehe leider nicht, wo hier der Fehler liegt. Weil es mit dem, was ich selbst geschrieben hatte nicht funktioniert hat, habe ich es mit einem Code von einer der Rückmeldungen versucht. Gleiches Problem.

                        Was habe ich falsch gemacht?

                        Liebe Grüße
                        Poison

                        1. Hi,

                          Parse error: syntax error, unexpected '{' on line 4

                          Aaaah, ich habs selbst gefunden. Da war eine geschlossene, runde Klammer zu wenig.

                          Aber nun bekomme ich einen weiteren Fehler:

                          Parse error: syntax error, unexpected T_IF on line 50

                            
                          if(!$verbindung)  
                          {  
                          $error= "Leider ist ein Fehler bei der Registrierung aufgetreten. Bitte sende mir zur Registrierung eine E-Mail: <a href="mailto:mail@potionmaster.de">mail@potionmaster.de</a>";  
                          }  
                          else  
                          {  
                          
                          

                          Was kann ich statt dessen eingeben?
                          Mit "if(!mysql_connect("localhost", "Benutzername" , "Passwort"))" funktionierte es leider auch nicht.

                          Liebe Grüße
                          Poison

                          1. Hallo poison,

                            Aber nun bekomme ich einen weiteren Fehler:

                            Parse error: syntax error, unexpected T_IF on line 50

                            der Fehler ist in der Zeile vorher zu suchen, genauer gesagt: am Ende der Zeile vorher.

                            Gruß,
                            Tobias

                            1. Hi,

                              vielen Dank für eure Hinweise. Sehe vor lauter "", '' und " schon überhaupt nichts mehr. :-))

                              @Auge
                              Du hattest Recht, da kamen noch mehr Fehlermeldungen.

                              Einige dieser Fehler, die sich beim Schreiben eingeschlichen haben, konnte ich jetzt beheben. Nur bei diesem hier

                              Parse error: syntax error, unexpected '"', expecting T_STRING or T_VARIABLE or T_NUM_STRING on line 96

                              weiß ich jetzt wieder nicht weiter. Habe mir alles vor Zeile 96 nochmal durchgesehen, ob ich irgendwas nicht maskiert, ein Anführungszeichen oder ein Semikolon vergessen habe. Für mich sieht alles gut aus. Habe es auch noch mit Beispielen im Internet verglichen.

                                
                              if($menge == 0)  
                              {  
                              $eintrag = "INSERT INTO login (username, passwort, email) VALUES ('" . mysql_real_escape_string($_POST["username"]) . "', '" . mysql_real_escape_string($passwort) . "', '" . mysql_real_escape_string($_POST["email"]) . "')";  
                              $eintragen = mysql_query($eintrag);  
                              }  
                                
                                
                              if($eintragen == "true")  
                              {  
                              $error = "Hallo <b>$_POST["username"]</b>, Du hast Dich erfolgreich registriert. <a href=\"anmelden.php\">Anmelden</a>";  
                              }  
                              else  
                              {  
                              $error = "Deine Registrierung ist leider fehlgeschlagen. Sollte Deine Registrierung nochmals fehlschlagen,  
                              sende mir bitte eine E-Mail: <a href=\"mailto:mail@potionmaster.de\">mail@potionmaster.de</a>  
                              <br>  
                              <br>  
                              <a href=\"eintragen.html\">Zurück</a>";  
                              }  
                              
                              

                              Der Befehl "if($menge == 0)" steht in Reihe 87. In Reihe 83 tauchte der letzte Fehler auf und ist behoben. Die Zeilen 84-87 sind leer. Liegt es vielleicht daran?
                              Aber dann würde ja die Fehlermeldung nicht passen.

                              Ich dachte schon, dass es vielleicht an dieser Stelle ...($_POST["email"]) . "')";  ... liegt, weil die schließende, runde Klammer vor dem letzten Anführungszeichen liegt. Aber das dürfte korrekt sein, weil die Anführungszeichen zum öffnen des kompletten Strings nicht innerhalb, sondern ebenfalls außerhalb bzw. vor der öffnenden, runden Klammer liegen. Oder ist das ein Denkfehler?

                              Oh, ich werd nochmal wahnsinnig.

                              Liebe Grüße
                              Poison

                              1. Hallo Poison,

                                Parse error: syntax error, unexpected '"', expecting T_STRING or T_VARIABLE or T_NUM_STRING on line 96

                                weiß ich jetzt wieder nicht weiter. Habe mir alles vor Zeile 96 nochmal durchgesehen,

                                Der Fehler muss nicht immer vor der angegebenen Zeile sein, er kann auch wirklich in der Zeile die in der Fehlermeldung steht stecken - so auch hier:

                                $error = "Hallo <b>$_POST["username"]</b>, Du hast Dich erfolgreich registriert. <a href="anmelden.php">Anmelden</a>";

                                Du beendest mit dem Anführungszeichen nach »$_POST[« den String den du $error zuweisen willst - da anschließend aber was kommt was PHP da nicht erwartet, bekommst du die Zeile eben in Form einer Fehlermeldung um die Ohren gehauen.

                                Gruß,
                                Tobias

                                1. Hi Tobias,

                                  Du beendest mit dem Anführungszeichen nach »$_POST[« den String den du $error zuweisen willst - da anschließend aber was kommt was PHP da nicht erwartet, bekommst du die Zeile eben in Form einer Fehlermeldung um die Ohren gehauen.

                                  Das habe ich mir schon gedacht und bevor ich gepostet habe, folgendes ausprobiert:

                                  statt $_POST["username"] habe ich es mit $_POST['username'] oder $_POST["username"] probiert.

                                  Dann wird aus der Fehlermeldung

                                  Parse error: syntax error, unexpected '"', expecting T_STRING or T_VARIABLE or T_NUM_STRING on line 96

                                  das hier

                                  Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING on line 96

                                  Ist es besser ich wandle das $_POST["username"] am Anfang in ein $username um? Dann bräuchte ich die Anführungszeichen in dem Satz gar nicht. Ich weiß mir nicht mehr zu helfen.

                                  Liebe Grüße
                                  Poison

                                  Gruß,
                                  Tobias

                              2. Hi!

                                vielen Dank für eure Hinweise. Sehe vor lauter "", '' und " schon überhaupt nichts mehr. :-))

                                Das ist aber wichtig, denn beim Schachteln von Kontexten muss man stets die Übersicht behalten. Du kannst ja mal zur Übung (alternativ: vollständigen Verwirrung) versuchen, einen String in JavaScript-Code zu notieren, der Anführungszeichen enthält und der in einem Attribut eines HTML-Elements steht, das von PHP ausgegeben werden soll.

                                alert("foo "bar" baz");
                                <span onclick="alert("foo "bar" baz");">foo</span>
                                echo "<span onclick="alert("foo "bar" baz");">foo</span>";

                                In der Form ist das natürlich fehlerhaft. Wie kann man es richtig machen? Und zum Erschweren kannst du auch eine Variante suchen ohne 'einfache Anführungszeichen' zu verwenden. Vielleicht nützt es dir etwas, wenn du dich mit der Funktion sprintf() in ihrer einfachsten Anwendungsweise vertraut machst, also nur den Platzhalter %s für Strings betrachtest. Mit der Funktion kann man das Notieren einiger Schachtelungsebenen und damit Backslash-Wälder umgehen. Siehe http://wiki.selfhtml.org/wiki/Artikel:Kontextwechsel/erkennen_und_behandeln#JavaScript_und_HTML

                                Parse error: syntax error, unexpected '"', expecting T_STRING or T_VARIABLE or T_NUM_STRING on line 96
                                $error = "Hallo <b>$_POST["username"]</b>, Du hast Dich erfolgreich registriert. <a href="anmelden.php">Anmelden</a>";

                                Hier hast du eine Besonderheit PHPs, die sich aber bei Beachtung des Kontextwechsels "Variableninhalt im HTML-Code ausgeben" von selbst auflöst, denn du musst auf $_POST["username"] noch htmlspecialchars() anwenden.

                                $error = sprintf('Hallo <b>%s</b>, Du hast Dich erfolgreich registriert. <a href="anmelden.php">Anmelden</a>', htmlspecialchars($_POST["username"]));

                                Die Besonderheit war, dass man ja Variablen in ""-Strings notieren kann und dabei auch solch komplexe Dinge wie Array-Elemente einfügen können muss. Alle falschen und richtigen Varianten stehen im PHP-Handbuch: http://de.php.net/manual/en/language.types.string.php#language.types.string.parsing. Achte auf:

                                error_reporting(E_ALL); // Notice-Meldungen anzeigen
                                $foo = array('bar' => 'qux');

                                echo $foo[bar]; // falsch
                                echo $foo["bar"]; // richtig
                                echo "bla $foo[bar] fasel"; // richtig, _obwohl_ keine Anführungszeichen notiert sind
                                echo "bla {$foo[bar]} fasel"; // falsch, _weil_ Anführungszeichen fehlen
                                echo "bla {$foo["bar"]} fasel"; // richtig

                                Noch was anderes:

                                if($eintragen == "true")

                                Hier möchtest du nicht auf die Zeichenkette "true" sondern auf den speziellen Wert true testen. Diesen Fehler würdest du gar nicht bemerken, weil diese Stelle intentionsgemäß funktioniert. Das liegt aber daran, dass ein String, der nicht leer ist oder '0' enthält, im boolschen Kontext als true angesehen wird. Andererseits kann man sich das explizite Testen auf true schenken und muss nur

                                if ($eintragen)

                                notieren, denn "Ist es wahr, dass $eintragen wahr ist?" ist doppelt gemoppelt, ein "Ist $eintragen wahr" reicht auch.

                                Oh, ich werd nochmal wahnsinnig.

                                Kühlen Kopf behalten!

                                Lo!

                                1. Hi,

                                  Parse error: syntax error, unexpected '"', expecting T_STRING or T_VARIABLE or T_NUM_STRING on line 96
                                  $error = "Hallo <b>$_POST["username"]</b>, Du hast Dich erfolgreich registriert. <a href="anmelden.php">Anmelden</a>";

                                  Ich habe es jetzt hingekriegt, indem ich

                                  "Hallo <b>".$_POST['username']."</b>,

                                  gemacht habe.

                                  Nun sind alle STRING-Fehler soweit mal ausgemerzt. Zumindest kommen keine Fehlermeldungen mehr.

                                  Dafür erhalte ich nun eine Warnung.

                                  Warning: mysql_close() expects parameter 1 to be resource, null given

                                  Ich habe verstanden, dass zum Schließen der Datenbank auch eine vorhanden sein muss und offensichtlich findet PHP in meinem Script keine.

                                  Der Befehl   mysql_close($verbindung);   steht bei mir ganz am Ende des Scripts. Sollte ich ihn direkt auf den Teil folgen lassen, indem ich Daten in die Datenbank schreibe, oder hat das damit nichts zu tun?

                                  Oh, und dann ist mir noch was aufgefallen.
                                  Also, ich habe das mit dem EVA-Prinzip endlich geblickt und wie du gesehen hast, "echo" überall durch "$error" ersetzt und am Ende des Scripts

                                    
                                  if (!empty($error))  
                                  {  
                                  echo '<div class="error"><p>'.$error.'</p></div>';  
                                  }  
                                  else  
                                  {  
                                  echo $output;  
                                  }  
                                  
                                  

                                  angehängt.
                                  Bei dieser Meldung

                                    
                                  $error = "Hallo <b>$_POST["username"]</b>, Du hast Dich erfolgreich registriert. <a href=\"anmelden.php\">Anmelden</a>";  
                                  
                                  

                                  handelt es sich ja nicht um eine Fehlermeldung. Gebe ich das trotzdem mit "$error" ein?

                                  Liebe Grüße
                                  Poison

                                  1. Hi!

                                    Parse error: syntax error, unexpected '"', expecting T_STRING or T_VARIABLE or T_NUM_STRING on line 96
                                    $error = "Hallo <b>$_POST["username"]</b>, Du hast Dich erfolgreich registriert. <a href="anmelden.php">Anmelden</a>";

                                    Ich habe es jetzt hingekriegt, indem ich

                                    "Hallo <b>".$_POST['username']."</b>,

                                    gemacht habe.

                                    Und wo ist das htmlspecialchars() abgeblieben? Es gibt Leute, die behaupten, sie heißen: <script>location.href='http://example.org'</script>
                                    Wann immer nun ihr Name ausgegeben werden soll, ist deine Seite nur noch ein Eintrag in der History des Browsers deiner Besucher. Du kannst nicht verhindern, dass sie solchen Unsinn eingeban, aber durch die Kontextwechselbeachtung kannst du verhindern, dass der Unsinn Schaden anrichtet.

                                    Warning: mysql_close() expects parameter 1 to be resource, null given

                                    Du brauchst die Verbindung nicht zu schließen, besonders dann nicht, wenn das Script-Ende in Sicht ist, denn da räumt PHP sowieso auf. Ein explizites Schließen ist dann sinnvoll, wenn das Script mit einer umfangreichen Berechnung noch eine Weile weiterläuft und man die Datenbankressourcen wieder freigeben will.

                                    Ich habe verstanden, dass zum Schließen der Datenbank auch eine vorhanden sein muss und offensichtlich findet PHP in meinem Script keine.
                                    Der Befehl   mysql_close($verbindung);   steht bei mir ganz am Ende des Scripts. Sollte ich ihn direkt auf den Teil folgen lassen, indem ich Daten in die Datenbank schreibe, oder hat das damit nichts zu tun?

                                    $verbindung muss das sein, was mysql_connect() im Nicht-Fehlerfall zurückgegeben hat. error_reporting(E_ALL) steht während deiner Tests irgendwo am Script-Anfang? Damit bekommst du Notice-Meldungen ausgegeben, wann immer du auf nicht vorhandene Variablen zuzugreifen versuchst. Solche Notice-Meldungen deuten einerseits auf Tippfehler in Variablennamen hin, andererseits auch auf Fehler in der Ablauf-Logik. Es gibt also Wege im Script, auf denen das Erzeugen von Variablen umgangen wurde, obwohl später darauf zugegriffen wird.

                                    Bei dieser Meldung
                                    $error = "Hallo <b>$_POST["username"]</b>, Du hast Dich erfolgreich registriert. <a href=\"anmelden.php\">Anmelden</a>";
                                    handelt es sich ja nicht um eine Fehlermeldung. Gebe ich das trotzdem mit "$error" ein?

                                    Sinnvoll ist das nicht, denn du willst diesen Text ja nicht in rot als Fehlermeldung formatiert anzeigen lassen, sondern vielleicht eher in grün. Also darf es kein Eintrag in $error sein. Muss es überhaupt ein Eintrag in einer Variablen sein? Wenn alle Eingabedatenprüfungen erfolgreich absolviert wurden und auch die MySQL-Verarbeitung keinen $error produziert hat, sollte doch nur noch das erfolgreiche Registrieren übrigbleiben, oder? Dann würde doch im Ausgabe-Teil reichen, diesen Text im else-Zweig des if(!empty($error)) zu notieren (natürlich mit htmlspecialchars() um den Usernamen drumherum).

                                    Lo!

                                    1. Hi!

                                      irgendwie war ich gestern nicht mehr ganz auf der Höhe.

                                      Habe jetzt das

                                        
                                      error_reporting(E_ALL);  
                                      
                                      

                                      ganz oben in meinem Script angebracht.
                                      Außerdem habe ich im Handbuch das mit den htmlspecialchars() nachgelesen und mir deine Beispiele nochmal richtig angeguckt. Da ich die Zeile mit der Variablen im Text nicht als $error ausgeben sollte, habe ich folgendes gemacht:

                                        
                                      "Hallo <b>{".$_POST['username']."}</b>,...  
                                      
                                      

                                      Wäre das so richtig? Eine Fehlermeldung wurde zumindest nicht ausgegeben.

                                      ABER:
                                      Müsste ich nicht alle Zeichen, die was mit HTML zu tun haben in meinem PHP Script mit htmlspecialchars() bearbeiten? Also:

                                        
                                      "Hallo &lt;b&gt;{".$_POST['username']."}&lt;/b&gt;,...  
                                        
                                      ... &lt;a href=\"anmelden.php\"&gt;Anmelden&lt;/a&gt;";  
                                      
                                      

                                      Oder ist das falsch gedacht?

                                      Nachdem ich // mysql_close($verbindung); // aus dem Script entfernt habe, kommt auch keine Warnung mehr. Ich dachte, bei PHP muss alles korrekt sein? Warum wird ein (indirekter) Fehler angezeigt, wenn man es korrekt machen möchte? (am Kopf kratz!!)

                                      Ich habe noch eine Frage. Ich möchte, dass meine Besucher beim registrieren ihre Mailadresse mit angeben müssen. Kann ich diesen Codeschnipsel benutzen, um die Richtigkeit der Mailadresse abzufragen?

                                        
                                      if(check_email($email))  
                                      {  
                                      $nonascii      = "\x80-\xff"; # Non-ASCII-Chars are not allowed  
                                        
                                      $nqtext        = "[^\\\\$nonascii\015\012\"]";  
                                      $qchar         = "\\\\[^$nonascii]";  
                                        
                                      $protocol      = '(?:mailto:)';  
                                        
                                      $normuser      = '[a-zA-Z0-9][a-zA-Z0-9_.-]*';  
                                      $quotedstring  = "\"(?:$nqtext|$qchar)+\"";  
                                      $user_part     = "(?:$normuser|$quotedstring)";  
                                        
                                      $dom_mainpart  = '[a-zA-Z0-9][a-zA-Z0-9._-]*\\.';  
                                      $dom_subpart   = '(?:[a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*';  
                                      $dom_tldpart   = '[a-zA-Z]{2,5}';  
                                      $domain_part   = "$dom_subpart$dom_mainpart$dom_tldpart";  
                                        
                                      $regex         = "$protocol?$user_part\@$domain_part";  
                                        
                                      return preg_match("/^$regex$/",$email);  
                                      }  
                                      else  
                                      {  
                                      echo "Du musst eine korrekt E-Mail-Adresse angeben.  
                                      echo <a href=\"eintragen.html\">Zurück</a>";  
                                      
                                      

                                      Habe ich hier bei SELFHTML gefunden. Ist das in die if-else-Anweisung richtig eingebunden? Müsste ich hier noch was anpassen?

                                      Kann ich mein Script nochmal einstellen, damit du drüber guckst, ob soweit alles beachtet ist?

                                      Liebe Grüße
                                      Poison

                                      1. Hallo,

                                        Ich habe noch eine Frage. Ich möchte, dass meine Besucher beim registrieren ihre Mailadresse mit angeben müssen. Kann ich diesen Codeschnipsel benutzen, um die Richtigkeit der Mailadresse abzufragen?

                                        [...] Code aus Christian Kruses Artikel gekürzt [...}

                                        Habe ich hier bei SELFHTML gefunden. [...] Müsste ich hier noch was anpassen?

                                        Ja, müsstest Du. Darüber haben wir mal intensiv diskutiert :-)

                                        Freundliche Grüße

                                        Vinzenz

                                        1. Hi,

                                          "Hallo <b>{$_POST['username']}</b>,...

                                          Aber nun zu htmlspecialchars: Wenn du den Text nicht ausgeben willst, brauchst du ihn nicht zu erstellen. Da er aber da ist, soll er doch wohl auch ausgegeben werden. Zwar nicht gleich, aber im A-Teil (von EVA). Und weil du den Text an dieser Stelle schon zusammenbaust, musst du auch jetzt schon den Kontext beachten, also

                                          "Hallo <b>" . htmlspecialchars($_POST['username']) . "</b>,...

                                          notieren

                                          OK, jetzt, wo ich dein Beispiel sehe, habe ich es glaube ich endlich begriffen. Ich muss das Wort "htmlspecialchars" verwenden und in die runden Klammern den Wert einfügen, den ich damit in Verbindung bringen möchte. "htmlspecialchars ()" hat nichts mit dem Kontextwechsel zu tun, das hab ich nämlich durcheinander gebracht. Bin schon voll Panne!

                                          Wenn ich dich richtig verstanden habe, verwende ich "htmlspecialchars ()" nur bei der Besonderheit, wenn ich eine Variable im Text ausgebe. Oder gibt es noch andere Verwendungsmöglichkeiten/-vorgaben?

                                          ABER:
                                          Müsste ich nicht alle Zeichen, die was mit HTML zu tun haben in meinem PHP Script mit htmlspecialchars() bearbeiten? Also:

                                          "Hallo &lt;b&gt;{".$_POST['username']."}&lt;/b&gt;,...

                                          ... &lt;a href="anmelden.php"&gt;Anmelden&lt;/a&gt;";

                                          
                                          > > Oder ist das falsch gedacht?  
                                          >   
                                          > Ja, falsch gedacht. Du willst ja HTML-Code an den Browser senden, also müssen die <> schon so bleiben, wie sie sind. Als &lt;&gt; notiert würde der Browser die Zeichen <> hinschreiben, anstatt sie als Tag-Begrenzer zu interpretieren.  
                                            
                                          Nachdem du es mir in anderen Worten nochmal erklärt hast, habe ich es (hoffentlich) begriffen.  
                                            
                                            
                                          
                                          > > Nachdem ich // mysql\_close($verbindung); // aus dem Script entfernt habe, kommt auch keine Warnung mehr. Ich dachte, bei PHP muss alles korrekt sein? Warum wird ein (indirekter) Fehler angezeigt, wenn man es korrekt machen möchte? (am Kopf kratz!!)  
                                          >   
                                          > Du hast irgendwo einen Fehler drin. Wenn $verbindung wirklich eine Ressourcenkennung beinhaltet, wie sie von mysql\_connect() erzeugt worden ist, darf es keinen Fehler geben. Wenn aber aus irgendeinem Grunde was anderes (oder nichts/null) enthält, dann gibt es die Warnung.  
                                            
                                          Ich habe den Befehl zum Schließen der Datenbank nun direkt nach dem Schreiben in die Datenbank gesetzt und... die Fehlermeldung taucht nicht mehr auf. Weiter unten kam der Befehl "mysql\_close" wohl einfach zu spät, PHP hatte, wie die es ausgedrückt hast, schon "aufgeräumt".  
                                            
                                          Wegen der Abfrage zur Mailadresse. Aus Vinzenz Beitrag (Diskussion zu dem Thema) habe ich herausgelesen, dass er keine definitiv sicher Abfrage zur gültigen Mailadresse geben kann. Zumindest nicht so einfach, wie ich es mir vorgestellt habe. Da ich meine Besucher in den Regeln und FAQ zu meiner Seite darauf hinweise, dass sie eine "funktionierende" Mailadresse brauchen, das sie sonst an manchen Spielen, Rätseln oder Abenteuern eventuell nicht teilnehmen können, denke ich, muss jeder User selbst entscheiden, ob er bei der Abfrage im Anmeldeformular Quatsch eingibt oder nicht.  
                                            
                                          Muss ich dann hierzu noch was beachten, damit mir nicht jemand mit der Eingabe von einer seltsamen Mailadresse, einen Code unterjubeln kann oder ist das Thema mit "mysql\_real\_escape\_string" schon erledigt?  
                                            
                                          Ich schreibe mir gerade ein Word Dokument zusammen, indem ich alles, was ich beim Schreiben eines Scripts beachten sollte (Kontextwechsel, htmlspecialchars(), Vergleiche usw.) aufführe, damit ich einen roten Faden habe, an dem ich mich entlang hangeln kann (und hoffentlich nicht wieder was wichtiges vergesse!!).  
                                            
                                          Trotzdem wäre ich dankbar, ihr würdet über das Login-Script nochmal drübergucken:  
                                            
                                          ~~~php
                                            
                                          <?php  
                                          error_reporting(E_ALL);  
                                            
                                          if(empty($_POST["passwort"]) or empty($_POST["passwort2"]) or empty($_POST["username"]) or empty($_POST["email"]))  
                                          {  
                                          $error = "Du hast leider nicht alle Felder ausgefüllt.  
                                          <br>  
                                          <br><a href=\"eintragen.html\">Zurück</a>";  
                                          }  
                                          else  
                                          {  
                                          // Alle Felder ausgefüllt, weitere Verarbeitung  
                                          // Daten für die Ausgabe werden samt HTML-Schnipseln in $output geschrieben.  
                                            
                                            
                                          /*Alternative  
                                            
                                          if(empty($_POST["passwort"])  
                                          {  
                                          echo "Du hast kein Passwort angegeben. <a href=\"eintragen.html\">Zurück</a>";  
                                          }  
                                            
                                          else if(empty($_POST["passwort2"])  
                                          {  
                                          echo "Du hast vergessen Dein Passwort erneut einzugeben. <a href=\"eintragen.html\">Zurück</a>";  
                                          }  
                                            
                                          else if(empty($_POST["username"])  
                                          {  
                                          echo "Du hast keinen Benutzernamen angegeben. <a href=\"eintragen.html\">Zurück</a>";  
                                          }  
                                            
                                          else if(empty($_POST["email"])  
                                          {  
                                          echo "Du hast keine E-Mail-Adresse angegeben. <a href=\"eintragen.html\">Zurück</a>";  
                                          }  
                                          else  
                                          {  
                                            
                                          Alternative Ende*/  
                                            
                                            
                                            
                                          if($_POST["passwort"] != $_POST["passwort2"])  
                                          {  
                                          $error = "Deine Passwörter sind leider nicht identisch. <a href=\"eintragen.html\">Zurück</a>";  
                                          }  
                                          else  
                                          {  
                                            
                                            
                                          $verbindung = mysql_connect("localhost", "Vesta" , "vesta");  
                                            
                                          if(!$verbindung)  
                                          {  
                                          $error = "Leider ist ein Fehler bei der Registrierung aufgetreten. Bitte sende mir zur Registrierung  
                                          eine E-Mail: <a href=\"mailto:mail@potionmaster.de\">mail@potionmaster.de</a>";  
                                          }  
                                          else  
                                          {  
                                            
                                            
                                          mysql_select_db("homepage");  
                                            
                                            
                                          if(!mysql_select_db("homepage"))  
                                          {  
                                          $error = "Leider ist ein Fehler bei der Registrierung aufgetreten. Bitte sende mir zur Registrierung  
                                          eine E-Mail: <a href=\"mailto:mail@potionmaster.de\">mail@potionmaster.de</a>";  
                                          }  
                                          else  
                                          {  
                                            
                                            
                                          $passwort = md5($_POST["passwort"]);  
                                            
                                          $result = mysql_query("SELECT id FROM login WHERE username= '" . mysql_real_escape_string($_POST["username"]) . "'");  
                                          $menge = mysql_num_rows($result);  
                                            
                                          if($menge == 0)  
                                          {  
                                          $eintrag = "INSERT INTO login (username, passwort, email) VALUES ('" . mysql_real_escape_string($_POST["username"]) . "', '" . mysql_real_escape_string($passwort) . "', '" . mysql_real_escape_string($_POST["email"]) . "')";  
                                          $eintragen = mysql_query($eintrag);  
                                          }  
                                          else  
                                          {  
                                          $error = "Der Benutzername ist schon vergeben. Du musst einen anderen wählen.  
                                          echo  <a href=\"registrieren1.php\">Zurück</a>";  
                                          }  
                                            
                                          if(!$eintragen)  
                                          {  
                                          $error = "Deine Registrierung ist leider fehlgeschlagen. Sollte Deine Registrierung nochmals fehlschlagen,  
                                          sende mir bitte eine E-Mail: <a href=\"mailto:mail@potionmaster.de\">mail@potionmaster.de</a>  
                                          <a href=\"eintragen.html\">Zurück</a>";  
                                          }  
                                          else  
                                          {  
                                          mysql_close($verbindung);  
                                          }  
                                          //schließen der noch offenen "else" Anweisungen  
                                          }  
                                          }  
                                          }  
                                          }  
                                            
                                          if (!empty($error))  
                                          {  
                                          echo '<div class="error"><p>'.$error.'</p></div>';  
                                          }  
                                          else  
                                          {  
                                          echo "Hallo <b>".htmlspecialchars($_POST['username'])."</b>, Du hast Dich erfolgreich registriert. <a href=\"anmelden.php\">Anmelden</a>";  
                                          }  
                                          ?>  
                                          
                                          

                                          So.
                                          Fehlt noch irgendwas? Habe ich vielleicht doch noch was vergessen?
                                          Bin trotz der ganzen Verwirrung, dankbar über weitere Anregungen/Tipps.

                                          @dedlfix
                                          Ich habe mir dein Beispiel angesehen und auch den Artikel gelesen. Leider muss ich gestehen, es wird immer verwirrender für mich.
                                          Aber ich würde das Beispiel auf diese Weise verändern:

                                          alert('foo "bar" baz');
                                          <span onclick="alert ('foo "bar" baz');">foo</span>
                                          echo ".<span onclick="alert('foo "bar" baz');">foo</span>.";

                                          Wäre das so richtig? Ich habe es bei mir auf dem Rechner getestet. Fehlermeldungen kamen keine. Aber ist das korrekt, dass folgendes ausgegeben wird:

                                          alert('foo "bar" baz'); foo echo ".foo."

                                          Oder müsste etwas anderes ausgegeben werden und ich habe wieder falsch verstanden, was ich mit dem Beispiel tun sollte?

                                          Liebe Grüße
                                          Poison

                                          1. Hallo

                                            "Hallo <b>{$_POST['username']}</b>,...

                                            Aber nun zu htmlspecialchars: Wenn du den Text nicht ausgeben willst, brauchst du ihn nicht zu erstellen. Da er aber da ist, soll er doch wohl auch ausgegeben werden. Zwar nicht gleich, aber im A-Teil (von EVA). Und weil du den Text an dieser Stelle schon zusammenbaust, musst du auch jetzt schon den Kontext beachten, also

                                            "Hallo <b>" . htmlspecialchars($_POST['username']) . "</b>,...

                                            notieren

                                            OK, jetzt, wo ich dein Beispiel sehe, habe ich es glaube ich endlich begriffen. Ich muss das Wort "htmlspecialchars" verwenden und in die runden Klammern den Wert einfügen, den ich damit in Verbindung bringen möchte. "htmlspecialchars ()" hat nichts mit dem Kontextwechsel zu tun, das hab ich nämlich durcheinander gebracht. Bin schon voll Panne!

                                            Doch doch, htmlspecialchars hat mit dem Kontextwechsel zu tun. Du speicherst einen Text in einer Variable. Man spricht hier auch von einer Zeichenkette oder einem String. Hier wird er konkret von einem Besucher deiner Seite in einem Formular eingetragen und an dein Skript übermittelt, wo er als $_POST['username'] ankommt.

                                            Bis jetzt handelt es sich einfach nur um irgendeinen Text, der auch Zeichen enthalten *kann*, die im Kontext HTML eine schädliche Auswirkung haben. *Ob* der Besucher, egal ob mit Absicht oder aus Versehen, schädliche Zeichen eingibt, kannst du nicht wissen. Deshalb müssen diese Zeichen, so vorhanden, auf Verdacht maskiert und damit unschädlich gemacht werden, wenn man den Text innerhalb eines HTML-Dokuments ausgeben will. Das erledigt die *Funktion* htmlspecialchars, der du die Variable, in der der Text gespeichert ist, als Parameter übergibst. Als Rückgabewert der Funktion bekommst du den für die Ausgabe in HTML behandelten Text zurück.

                                            Findet die Funktion im Text eines oder mehrere der angesprochenen schädlichen Zeichen, werden sie, den Regeln von HTML entsprechend, maskiert. Sind keine solchen Zeichen im Text vorhanden, bekommst du den Text unverändert zurück.

                                            Tschö, Auge

                                            --
                                            Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
                                            Terry Pratchett, "Wachen! Wachen!"
                                            Veranstaltungsdatenbank Vdb 0.3
                                      2. Hi!

                                        Da ich die Zeile mit der Variablen im Text nicht als $error ausgeben sollte, habe ich folgendes gemacht:

                                        "Hallo <b>{".$_POST['username']."}</b>,...

                                        
                                        > Wäre das so richtig? Eine Fehlermeldung wurde zumindest nicht ausgegeben.  
                                          
                                        Nein. Zum einen wäre es richtig, entweder die {} ganz wegzulassen, denn die willst du ja nicht ausgeben. Oder du bleibst im String, dann muss du sie verwenden, weil PHP sie braucht, um die Variable richtig zu erkennen.  
                                          
                                          "Hallo <b>{$\_POST['username']}</b>,...  
                                          
                                        Aber nun zu htmlspecialchars: Wenn du den Text nicht ausgeben willst, brauchst du ihn nicht zu erstellen. Da er aber da ist, soll er doch wohl auch ausgegeben werden. Zwar nicht gleich, aber im A-Teil (von EVA). Und weil du den Text an dieser Stelle schon zusammenbaust, musst du auch jetzt schon den Kontext beachten, also  
                                          
                                          "Hallo <b>" . htmlspecialchars($\_POST['username']) . "</b>,...  
                                          
                                        notieren  
                                        
                                        > ABER:  
                                        > Müsste ich nicht alle Zeichen, die was mit HTML zu tun haben in meinem PHP Script mit htmlspecialchars() bearbeiten? Also:  
                                        > ~~~php
                                        
                                        "Hallo &lt;b&gt;{".$_POST['username']."}&lt;/b&gt;,...  
                                        
                                        >   
                                        > ... &lt;a href=\"anmelden.php\"&gt;Anmelden&lt;/a&gt;";
                                        
                                        

                                        Oder ist das falsch gedacht?

                                        Ja, falsch gedacht. Du willst ja HTML-Code an den Browser senden, also müssen die <> schon so bleiben, wie sie sind. Als &lt;&gt; notiert würde der Browser die Zeichen <> hinschreiben, anstatt sie als Tag-Begrenzer zu interpretieren.

                                        Nachdem ich // mysql_close($verbindung); // aus dem Script entfernt habe, kommt auch keine Warnung mehr. Ich dachte, bei PHP muss alles korrekt sein? Warum wird ein (indirekter) Fehler angezeigt, wenn man es korrekt machen möchte? (am Kopf kratz!!)

                                        Du hast irgendwo einen Fehler drin. Wenn $verbindung wirklich eine Ressourcenkennung beinhaltet, wie sie von mysql_connect() erzeugt worden ist, darf es keinen Fehler geben. Wenn aber aus irgendeinem Grunde was anderes (oder nichts/null) enthält, dann gibt es die Warnung.

                                        Bei PHP muss nicht zwangsläufig alles penibel korrekt sein. Deswegen ist es ja anfängerfreundlich, weil es so viel durchgehen lässt. Allerdings fördert es auch eine gewisse Schlampigkeit und ist dadurch in Verruf geraten.

                                        Ich habe noch eine Frage. Ich möchte, dass meine Besucher beim registrieren ihre Mailadresse mit angeben müssen. Kann ich diesen Codeschnipsel benutzen, um die Richtigkeit der Mailadresse abzufragen?

                                        Auch wenn du einen Prüfung findest, die die Syntax einer E-Mail-Adresse in irgendeiner Weise mehr oder weniger vollständig prüft, gibt dir das nicht die geringste Garantie, dass zu der Adresse auch ein Postfach existiert, das deine Mail anzunehmen bereit ist, und das dem Besucher auch gehört. Ich gebe beispielsweise gern "test@example.com" an, wenn irgendwer eine E-Mail-Adresse haben will, ich aber keinen Grund sehe, wofür er die nun unbedingt benötigt.

                                        Wenn du einigermaßen sichergehen willst, solltest du eine Bestätigungs-Mail versenden, auf die der Besucher reagieren muss. Es ist dann in Grunde genommen egal, ob die Mail nicht ankommt, weil er sich syntaktisch korrekt oder falsch vertippt hat oder weil er absichtlich eine falsche Angabe gemacht hat.

                                        Lo!

                          2. Hallo

                            Aber nun bekomme ich einen weiteren Fehler:

                            Parse error: syntax error, unexpected T_IF on line 50

                            if(!$verbindung)
                            {
                            $error= "Leider ist ein Fehler bei der Registrierung aufgetreten. Bitte sende mir zur Registrierung eine E-Mail: <a href="mailto:mail@potionmaster.de">mail@potionmaster.de</a>";
                            }
                            else
                            {

                            
                            >   
                            > Was kann ich statt dessen eingeben?  
                            > Mit "if(!mysql\_connect("localhost", "Benutzername" , "Passwort"))" funktionierte es leider auch nicht.  
                              
                            Da ist \*vorher\* irgendwas falsch. PHP meldet den Fehler, wo er für den Parser zu Tage tritt, die Ursache ist aber meist weiter oben zu suchen.  
                              
                            Wenn dieser Fehler gefunden und behoben ist, wirst du gleich den nächsten finden. Der ist ironischerweise in der Fehlermeldung versteckt. In Zeichenketten (Strings), die mit doppelten Anführungszeichen (") eingefasst sind, müssen doppelte Anführungszeichen, die zur Zeichenkette gehören, maskiert werden.  
                              
                            `$error= "... eine E-Mail: <a href=\"mailto:mail@potionmaster.de\">mail@potionmaster.de</a>";`{:.language-php}  
                              
                            Du kannst alternativ auch einfache Anführungszeichen zur Einfassung der Zeichenkette benutzen. Dort musst du dann die doppelten Anführungszeichen nicht maskieren. Nachteil an dieser Lösung ist, dass man keine Steuerzeichen als String (z.B. "\n") benutzen kann.  
                              
                            `$error= '... eine E-Mail: <a href="mailto:mail@potionmaster.de">mail@potionmaster.de</a>';`{:.language-php}  
                              
                            ... aber nicht ...  
                              
                            `$error= '... eine E-Mail: <a href="mailto:mail@potionmaster.de">mail@potionmaster.de</a>\n';`{:.language-php}  
                              
                            Umgekehrt geht das natürlich auch, wenn der Kontext, hier HTML, dies erlaubt (gemeint sind einfache Anführungszeichen für Attributwerte).  
                              
                            `$error= "... eine E-Mail: <a href='mailto:mail@potionmaster.de'>mail@potionmaster.de</a>";`{:.language-php}  
                              
                            Tschö, Auge  
                            
                            -- 
                            Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.  
                            Terry Pratchett, "Wachen! Wachen!"  
                              
                            [Veranstaltungsdatenbank Vdb 0.3](http://termindbase.auge8472.de/)
                            
      2. Mitnichten ist dann alles dicht genug

        Ok den Rest hab ich nicht gemeint, ich hab das nur auf die Sache mit dem verschlüsselten Passwort bezogen.