Professor Hase: Frage zu 'mysql_real_escape_string'

Hallo Forum,

ich habe (zum Üben) ein Beispielformular, das mir mit 'GET' 2 Variablen, einen Vor- und einen Familiennamen, an die Datei vorschau.php übergibt.

Das Ganze habe ich in 2 Versionen versucht.

Version 1 (Auszug aus dem Quellcode):

  
<?php  
$vorname=$_POST['vorname'];  
$familienname=$_POST['familienname'];  
echo"<p>Der Vorname ist ".$vorname.".</p>\n";  
echo"<p>Der Familienname ist ".$familienname.".</p>\n";  
?>  

Version 2 ist _mit_ der 'mysql_real_escape_string'-Funktion (Auszug aus dem Quellcode):

  
<?php  
$vorname=mysql_real_escape_string($_POST['vorname']);  
$familienname=mysql_real_escape_string($_POST['familienname']);  
echo"<p>Der Vorname ist ".$vorname.".</p>\n";  
echo"<p>Der Familienname ist ".$familienname.".</p>\n";  
?>  

Wenn ich jetzt als eine der beiden Variablen ein Anführungszeichen mitgebe, dann gibt Beispiel 1 Folgendes aus =>  /"

Im 2. Fall gibt die Vorschauseite Folgendes aus => ///"

Wieso wird auch im ersten Fall etwas maskiert? Und wieso 3 Maskierungszeichen im 2. Fall? Kann mir das wer näher erklären bitte? Wieso ist im ersten Fall, wo _kein_ 'mysql_real_escape_string' dabei ist, ein Maskierungszeichen? (Wenn das automatisch geschieht, wozu dann die Funktion?)<warnung>Bin aber _völliger_ Anfänger bei der Thematik</warnung>!

Alle 4 Dateien sind xhtml 1.0 valide und utf-8 codiert.

Beispiel 1 ohne der Funktion

Beispiel 2 mit der Funktion

Ich bedanke mich im Voraus für jede Hilfe!

Mit freundlichen Grüßen

Professor Hase

  1. hi

    Wieso wird auch im ersten Fall etwas maskiert?

    weil es die einstellung magicquotes_gpc oder so gibt. meistens ist ein server
    so konfiguriert, dass automatisch alle gets, posts und cookies escaped werden.

    »»Und wieso 3 Maskierungszeichen im 2. Fall?
    der schon escapte string wird noch mal escaped. aus / wird //, aus " wird /".
    so wird aus /" (was durch die magicquotes passiert ist), ein ///"

    Nick

    1. Hallo Nick,

      so wird aus /" (was durch die magicquotes passiert ist), ein ///"

      nein, gib mal bei Beispiel 2 nur ein " ein ... und es wird ein ///" draus werden!

      Professor Hase

      1. das ist mir schon klar.
        php macht erst selbst aus dem " ein /", dann machst du nochmal per
        mysql_real_escape_string ein ///" draus. der string wird also 2 mal escaped,
        einmal von php (wegen magicquotes_gpc), und dann noch einmal von dir selbst.

        falls du an einem opensourceprojekt arbeitest, das für die ganze welt
        verfügbar sein soll, würde ich an deiner stelle prüfen, ob die magicquotes in
        php eingeschaltet sind. sonst wird der string auf einigen servern 2 mal escaped
        auf einigen servern nur ein mal.

        Nick

    2. Hello,

      »»Und wieso 3 Maskierungszeichen im 2. Fall?
      der schon escapte string wird noch mal escaped. aus / wird //, aus " wird /".
      so wird aus /" (was durch die magicquotes passiert ist), ein ///"

      Allerdings bleibt das Maskierungszeichen bei magic_quotes immer noch der Backslash \ und nicht der von Dir hier gezeigte Slash oder Vorwärtsschrägstrich /

      Ein harzliches Glückauf

      Tom vom Berg

      --
      Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
  2. Hi,

    Version 2 ist _mit_ der 'mysql_real_escape_string'-Funktion

    diese Funktion hat in diesem Kontext gar nichts zu suchen. Was meinst Du, wofür "mysql" steht?

    Wenn ich jetzt als eine der beiden Variablen ein Anführungszeichen mitgebe, dann gibt Beispiel 1 Folgendes aus =>  /"

    das zeigt, dass auf dem Server magic_quotes_gpc aktiviert sind. Wenn Du dies nicht ändern kannst, musst Du die Funktion stripcslashes() anwenden.

    freundliche Grüße
    Ingo

    1. echo $begrüßung;

      Version 2 ist _mit_ der 'mysql_real_escape_string'-Funktion
      diese Funktion hat in diesem Kontext gar nichts zu suchen. Was meinst Du, wofür "mysql" steht?

      Naja, es handelt sich ja hier nur um einen Test. Ich gehe mal nicht davon aus, dass er das in einer Produktivumgebung so anwenden möchte.

      Wenn ich jetzt als eine der beiden Variablen ein Anführungszeichen mitgebe, dann gibt Beispiel 1 Folgendes aus =>  /"
      das zeigt, dass auf dem Server magic_quotes_gpc aktiviert sind. Wenn Du dies nicht ändern kannst, musst Du die Funktion stripcslashes() anwenden.

      Die Umkenrfunktion zu addslashes(), das vom Magic-Quotes-Feature verwendet wird, ist stripslashes() (ohne c).

      Ansonsten sei auf das Kapitel Magic Quotes des PHP-Handbuchs verwiesen, da finden sich auch Vorschläge zum Deaktivieren und ein Stückchen Code zum Gegenwirken, wenn das Ausschalten nicht möglich ist.

      echo "$verabschiedung $name";

  3. Hi,

    Wenn ich jetzt als eine der beiden Variablen ein Anführungszeichen mitgebe, dann gibt Beispiel 1 Folgendes aus =>  /"

    Im 2. Fall gibt die Vorschauseite Folgendes aus => ///"

    Du luegst, oder beobachtest nicht aufmerksam, oder bist schlampig beim Erstellen deiner Problembeschreibungen - magic_quotes maskiert natuerlich mit einem Backslash, also " bzw. \".

    MfG ChrisB

    --
    "The Internet: Technological marvel of marvels - but if you don't know *what* you're lookin' for on the Internet, it is nothing but a time-sucking vortex from hell."
  4. Hallo Forum,

    jetzt habe ich noch eine weitere Frage. Kann mir bitte jemand erklären, was beim Beispiel 3 auf der php-Homepage zur Querrybehandlung (Optimale Vorgehensweise zur Querybehandlung) das "VALUES ('%s', '%s', %d)" bedeutet und wofür es gut ist?

    Die _einfache_ INSERT-Erklärung auf der Schattenbaum-HP ist mir klar. Was macht obiges Beispiel durch das "VALUES ('%s', '%s', %d)" besser/sicherer bzw.  was ist das/wofür ist das da?

    Danke und mit freundlichen Grüßen

    Professor Hase

    1. echo $begrüßung;

      Kann mir bitte jemand erklären, was beim Beispiel 3 auf der php-Homepage zur Querrybehandlung (Optimale Vorgehensweise zur Querybehandlung) das "VALUES ('%s', '%s', %d)" bedeutet und wofür es gut ist?

      Das sind Platzhalter, die die Funktion sprintf() auswertet und durch die nachfolgenden Parameterwerte ersetzt. Es ist im Prinzip nur eine andere Art, einen String aus festen und variablen Bestandteilen zusammenzusetzen. In meinen Augen jedoch eine übersichtlichere, weil das SQL-Statement vollständig, in einem Teil notiert ist (wenn auch mit Platzhaltern statt Werten) und nicht ständig durch Stringende-Stringverknüpfung-Stringanfang unterbrochen wird.

      Die _einfache_ INSERT-Erklärung auf der Schattenbaum-HP ist mir klar. Was macht obiges Beispiel durch das "VALUES ('%s', '%s', %d)" besser/sicherer bzw.  was ist das/wofür ist das da?

      Leider krankt diese Tutorialseite an den altbekannten Anfängerunsitten und -fehlern. Zum einen ist da das übliche unsinnige Umkopieren der Eingabewerte in andere Variablen enthalten, und zum anderen fehlt die kontextgerechte Behandlung der Werte, die unter anderem auch dem Schutz gegenüber SQL-Injection dient.

      echo "$verabschiedung $name";

      1. Hi dedlfix!

        Das sind Platzhalter, die die Funktion sprintf() auswertet und durch die nachfolgenden Parameterwerte ersetzt. Es ist im Prinzip nur eine andere Art, einen String aus festen und variablen Bestandteilen zusammenzusetzen. In meinen Augen jedoch eine übersichtlichere, weil das SQL-Statement vollständig, in einem Teil notiert ist (wenn auch mit Platzhaltern statt Werten) und nicht ständig durch Stringende-Stringverknüpfung-Stringanfang unterbrochen wird.

        Es tut mir leid, ich habe _keine Ahnung_, wovon Du sprichst. =(

        Gibts die Erklärung auch für Dummys, so wie mich?

        Ich habe das Beispiel jetzt übrigens für eine Testseite von mir übernommen.
        Ich habe eine Datenbank mit der Tabelle "gbtabelle1". Dort gibt es 3 Felder.  Ein ID-Feld (wird automatisch eingetragen), das Feld "gbtb1_vorname" und das Feld "gbtb1_familienname" Letztere sind beide angelegt als Textfelder, Kollation ist "utf8_unicode_ci".

        Es kommt KEINE Fehlermeldung, allerdings werden die Datensätze nicht eingetragen. Woran _das_ liegt, verstehe ich auch nicht.

          
           <?php  
            include("../../../../../outsourcing/datenbank/dbverbindung.php");  
            // Die Verbindung zur Datenbank wird hergestellt.  
            if(get_magic_quotes_gpc())  
             {  
              $vorname=stripslashes($_POST["vorname"]);  
              $familienname=stripslashes($_POST["familienname"]);  
              // Wenn "get_magic_quotes_gpc" auf ON eingestellt ist, dann wird die automatische Maskierung entfernt.  
             }  
            else  
             {  
              $vorname=$_POST["vorname"];  
              $familienname=$_POST["familienname"];  
              // Wenn "get_magic_quotes_gpc" auf OFF eingestellt ist, dann werden die nicht automatisch maskierten Einträge übernommen.  
             }  
            echo"VOR dem query: Vorname = ".$vorname." und Nachname = ".$familienname;  
            $query = sprintf("INSERT INTO gbtabelle1 (`gbtb1_vorname`, `gbtb1_familienname`) VALUES ('%s', '%s',)",  
                            mysql_real_escape_string($vorname),  
                            mysql_real_escape_string($familienname)  
                            );  
          
                mysql_query($query);  
            mysql_close;  
           ?>  
        
        

        Woran liegt es, daß nichts eingetragen wird in die DB?

        Leider krankt diese Tutorialseite an den altbekannten Anfängerunsitten und -fehlern. Zum einen ist da das übliche unsinnige Umkopieren der Eingabewerte in andere Variablen enthalten, und zum anderen fehlt die kontextgerechte Behandlung der Werte, die unter anderem auch dem Schutz gegenüber SQL-Injection dient.

        Schade, das war eines der wenigen Dinge, die ich verstanden habe. *seufz*

        Danke für Deine Hilfe!!!!

        Prof. Hase

        1. Hallo,

          $query = sprintf("INSERT INTO gbtabelle1 (gbtb1\_vorname, gbtb1\_familienname) VALUES ('%s', '%s',)",
                              mysql_real_escape_string($vorname),
                              mysql_real_escape_string($familienname)
                              );

          eine Ausgabe der SQL-Anweisung zu Debugzwecken könnte Dir helfen.
          Du hast ein Komma zuviel darin.

          mysql_query($query);

          Warum prüfst Du nicht den Rückgabewert von mysql_query()?
          Du bekämst über mysql_error() eine Fehlermeldung von MySQL, die Dir sagte, dass Deine SQL-Anweisung einen Syntaxfehler aufweist.

          Ignorieren von Rückgabewerten und Fehlermeldungen ist _keine_ gute Fehlersuchstrategie. Skripte einfach sterben zu lassen - mit Ausgabe des Fehlers an den Benutzer - ist _keine_ gute Fehlerbehandlung ...

          Freundliche Grüße

          Vinzenz

          1. Hallo Vinzenz!

            eine Ausgabe der SQL-Anweisung zu Debugzwecken könnte Dir helfen.

            Wie? Was? Wer? Wo? Ich bin leider kein Programmierer ... _was_ soll ich tun???

            Du hast ein Komma zuviel darin.

            Ich habs grad gesehen. Das Komma hinter '%s' bei VALUES.

            Warum prüfst Du nicht den Rückgabewert von mysql_query()?
            Du bekämst über mysql_error() eine Fehlermeldung von MySQL, die Dir sagte, dass Deine SQL-Anweisung einen Syntaxfehler aufweist.

            *dumm dreinschau*

            Ignorieren von Rückgabewerten und Fehlermeldungen ist _keine_ gute Fehlersuchstrategie. Skripte einfach sterben zu lassen - mit Ausgabe des Fehlers an den Benutzer - ist _keine_ gute Fehlerbehandlung ...

            Ich _will_ ja alles gut und richtig machen ... ich versteh Dich nur einfach nicht. =...(

            Ich kapier einfach nicht, wovon Ihr (und sämtliche PHP-Seiten und Handbücher) sprecht. Paßt sonst noch was nicht im geposteten Code???

            Um nochmal auf dieses Beispiel 3 des PHP-Handbuchs zu kommen:

            Was ist der Vorteil, wenn ich hier die sprintf-Funktion nutze?

            Wieso ist das dritte Dingsbums in den Klammern nach VALUES plötzlich _nicht_ in Klammern?

            Mit freundlichen Grüßen

            Prof. Hase

            1. Ich sehe gerade ... jetzt werden die Daten zwar in die DB geschreiben, wenn ich mir dann aber via sqladmin die Datensätze ansehe, stehen die _komplett ident_ wie bei der Eingabe drin. Also " als ", /" als /" und was auch immer.

              Also _jetzt_ bin ich ja dann _endgültig_ verzweifelt. Wenn hier nichts maskiert wird, wozu dann alles? =(

              Professor Hase

              1. echo $begrüßung;

                Ich sehe gerade ... jetzt werden die Daten zwar in die DB geschreiben, wenn ich mir dann aber via sqladmin die Datensätze ansehe, stehen die _komplett ident_ wie bei der Eingabe drin. Also " als ", /" als /" und was auch immer.
                Also _jetzt_ bin ich ja dann _endgültig_ verzweifelt. Wenn hier nichts maskiert wird, wozu dann alles? =(

                Die Daten werden in einem SQL-Statement zusammen mit Anweisungsteilen notiert. Die Maskierung dient allein dem Zweck, dieses Zeichengemisch eindeutig zu halten, damit MySQL erkennen kann, was Daten sind und was Anweisung ist. Wenn das Statement erst einmal von MySQL geparst und in seine Einzelteile zerlegt worden ist, ist die Maskierung nicht mehr notwendig. Sie gehört ja nicht zu den Daten sondern ist nur die Transportsicherung. Ihre Aufgabe ist nun erledigt, sie wird für das Speichern in der Tabelle und auch beim Abfragen nicht mehr benötigt. Deswegen siehst du sie nicht mehr wieder. Wenn doch, dann ist irgendwas schief gelaufen (z.B. Magic Quotes nicht beachtet und zusätzlich zu Fuss maskiert).

                echo "$verabschiedung $name";

                1. Danke, vor allem für die lange Erklärung, ich muß mir das in Ruhe durchlesen. Eine _allerletzte_ Frage für heute.

                  Seit _Stunden_ versuche ich jetzt über das Forumsarchiv und mit GOOGLE herauszubekommen, wie man zählt, wie viele Datensätze in einer Tabelle sind.

                  Offensichtlich ist der resourcenschonenste Weg das "COUNT(*)"

                  Überall steht nur ... "mit COUNT(*)"

                  Schön und gut ... und wie kann ich diese Anzahl jetzt aich _auslesen_ und _ausgeben_, so daß zB.  "es sind soundsoviele Datensätze in einer Tabelle" dasteht?

                  Kannst Du mir _irgend_ ein Beispiel geben, wie ich ausgeben kann, wie viele Datensätze _insgesamt_ in einer Tabelle sind und ein Beispiel, wie viele Datensätze es mit einer bestimmten Regel sind, also etwas mit WHERE.

                  Danke

                  Prof. Hase

                  1. echo $begrüßung;

                    Überall steht nur ... "mit COUNT(*)"
                    Schön und gut ... und wie kann ich diese Anzahl jetzt aich _auslesen_ und _ausgeben_, so daß zB.  "es sind soundsoviele Datensätze in einer Tabelle" dasteht?

                    COUNT(*) wird in ein SELECT-Statement eingearbeitet, so als ob es ein abzufragendes Feld wäre. Man kann ihm auch noch einen Aliasnamen mit auf den Weg geben, dann bekommt diese berechnete Spalte einen richtigen Namen. Diese Query wird wie üblich mit mysql_query() abgesendet. Auch das Ergebnis-Abholen unterscheidet sich nicht vom üblichen Weg, nur dass man den mysql_fetch_...()-Aufruf nicht in eine Schleife zu legen braucht, weil nur ein einzelner Datensatz die Ergebnismenge bevölkert.

                    Kannst Du mir _irgend_ ein Beispiel geben, wie ich ausgeben kann, wie viele Datensätze _insgesamt_ in einer Tabelle sind und ein Beispiel, wie viele Datensätze es mit einer bestimmten Regel sind, also etwas mit WHERE.

                    SELECT COUNT(*) AS anzahl FROM tabelle
                      SELECT COUNT(*) AS anzahl FROM tabelle WHERE ...

                    echo "$verabschiedung $name";

            2. echo $begrüßung;

              eine Ausgabe der SQL-Anweisung zu Debugzwecken könnte Dir helfen.
              Wie? Was? Wer? Wo? Ich bin leider kein Programmierer ... _was_ soll ich tun???

              Was machst du dann mit PHP? Was bedeutet "ausgeben"? Etwas auf den Bildschirm schreiben. Bei PHP üblicherweise jedoch etwas in das HTML-Dokument schreiben, das der Browser zu sehen bekommt, damit man es dann am Bildschirm lesen kann.

              *dumm dreinschau*

              Ach komm, willst du nun was lernen oder dich hinter Gesichtsausdrücken verstecken?

              Wieso ist das dritte Dingsbums in den Klammern nach VALUES plötzlich _nicht_ in Klammern?

              Was ist Dingsbum in deinem Fall? Wie sieht das erzeugte SQL-Statement nun aus? (Kontrollausgabe mittels echo) An welcher Stelle hast du mit deinem PHP-Code ein Problem, das Statement zu erzeugen, das es gültiges SQL wird?

              echo "$verabschiedung $name";

        2. echo $begrüßung;

          Das sind Platzhalter, die die Funktion sprintf() auswertet und durch die nachfolgenden Parameterwerte ersetzt. Es ist im Prinzip nur eine andere Art, einen String aus festen und variablen Bestandteilen zusammenzusetzen. In meinen Augen jedoch eine übersichtlichere, weil das SQL-Statement vollständig, in einem Teil notiert ist (wenn auch mit Platzhaltern statt Werten) und nicht ständig durch Stringende-Stringverknüpfung-Stringanfang unterbrochen wird.

          Es tut mir leid, ich habe _keine Ahnung_, wovon Du sprichst. =(
          Gibts die Erklärung auch für Dummys, so wie mich?

          So ein SQL-Statement ist eine Mischung aus einem festen Anteil und variablen Werten. Letztere kommen aus deiner Eingabe und müssen in das SQL-Statement eingearbeitet werden.

          Am Ende möchtest du beispielsweise

          INSERT INTO tabelle (feld) VALUES ("wert")

          haben. Du hast da die drei Teile

          INSERT INTO tabelle (feld) VALUES ("
            wert
            ")

          die zusammengesetzt werden müssen. Eine einfache Methode ist die Verknüpfung von Strings:

          $sql = 'INSERT INTO tabelle (feld) VALUES ("' . $wert . '")';

          Nun muss aber auch noch berücksichtigt werden, dass bestimmte Zeichen eine besondere Bedeutung haben. Nachdem mit " ein String eingeleitet wurde, beendet ein weiteres " den String wieder. Kommt so ein " im Eingabewert vor, wird der nicht als Eingabe sondern als Stringende interpretiert. Die Folge ist bestenfalls ein Syntaxfehler. Aus diesem Grunde ist ein " als " zu notieren, dann erkennt der SQL-Server es als Datenbestandteil und nicht als Stringende an. Darum und um noch ein paar andere zu beachtende Zeichen kümmert sich die Funktion mysql_real_escape_string(). Der String wird nun also so gebildet:

          $sql = 'INSERT INTO tabelle (feld) VALUES ("' . mysql_real_escape_string($wert) . '")';

          Nun hast du hier einen Stringteil, dann einen PHP-Funktionsaufruf und am Ende noch ein Stück String. Dieses Beispiel hat nur einen variablen Wert. Wenn noch mehr dazukommen, wird diese Methode schnell unübersichtlich, weil immer mehr Stringverknüpfungen notiert werden müssen.

          $sql = 'INSERT INTO tabelle (feld1, feld2) VALUES ("' . mysql_real_escape_string($wert1) . '", "' . mysql_real_escape_string($wert2) . '")';

          Die Funktion sprintf() kann hier abhelfen. Eigentlich kann sie noch viel mehr, beispielsweise Zahlen zum Zwecke der Ausgabe formatieren, doch wir verwenden sie hier nur auf eine recht einfache Weise. Statt der variablen Werte wird der Platzhalter %s notiert. Der erste Parameter der Funktion sprintf() ist der String mit den Platzhaltern. Nun folgen genauso viele Argumente, wie im ersten String Platzhalter vorhanden sind. sprinf() fügt diese der Reihe nach bei den einzelnen Platzhaltern ein.

            $sql = sprintf('INSERT INTO tabelle (feld1, feld2) VALUES ("%s", "%s")',  
              mysql_real_escape_string($wert1),  
              mysql_real_escape_string($wert2));
          

          So hat man das SQL-Statement am Stück stehen und es nicht ständig von Stringoperationen unterbrochen.

          Wenn du wissen willst, was sprintf() nun fabriziert hat, machst du eine Kontrollausgabe. Das macht man immer dann, wenn irgendwo ein anderes Verhalten auftritt, als man erwartet hat, um sich zu überzeugen, dass die verwendeten Funktionen das Ergebnis bringen, das man sich vorgestellt hat.

          echo $sql;

          Es kommt KEINE Fehlermeldung, allerdings werden die Datensätze nicht eingetragen. Woran _das_ liegt, verstehe ich auch nicht.

          Die mysql_*-Funktionen haben die Angewohnheit im Stillen zu operieren. Wenn ein Fehler aufgetreten ist, melden sie das durch ihren Rückgabewert. Diesen musst du stets auswerten und dann darauf reagieren. Der Rückgabewert ist im Fehlerfall ein false, im Gutfall eine Ressourcenkennung. Gibst du nun einfach das false unbehandelt an die nachfolgende mysql_*-Funktion weiter, beschwert sich PHP mit dem berühmt-berüchtigten "supplied argument is not a valid MySQL result resource", weil false eben keine Ressourcenkennung ist. Doch das ist eher beim Abfragen das Problem, weil man da das Ergebnis von mysql_query() braucht, um die Datensätze abfragen zu können. Bei dir tut sich einfach nur nichts offensichtliches.

          Eine mögliche Vorgehensweise ist:

            if (! $connection = mysql_connect(...)) {  
              // Tut mir leid lieber Anwender, die Daten stehen grad nicht zur Verfügung. Bitte später nochmal probieren.  
              // echo mysql_error();  
            } else {  
              if (! $result = mysql_query($sql, $connection)) {  
                // Fehler aufgetreten. Anwender vertrösten.  
                // echo mysql_error();  
              } else {  
                // alles i.O.  
                // mach was mit dem Ergebnis. z.b. Abfragen  
              }  
            }
          

          Das echo mysql_error(); ist für Debuggingzwecke gut geeignet. Im produktiven Einsatz sollte man den Anwender nicht mit diesen technischen Details belästigen. Den Fehler sollte man anderweitig an den Administrator melden, z.B. Logfiles oder eine Mail senden.

          // Die Verbindung zur Datenbank wird hergestellt.
              if(get_magic_quotes_gpc())
               {
                $vorname=stripslashes($_POST["vorname"]);
                $familienname=stripslashes($_POST["familienname"]);
                // Wenn "get_magic_quotes_gpc" auf ON eingestellt ist, dann wird die automatische Maskierung entfernt.
               }
              else
               {
                $vorname=$_POST["vorname"];
                $familienname=$_POST["familienname"];
                // Wenn "get_magic_quotes_gpc" auf OFF eingestellt ist, dann werden die nicht automatisch maskierten Einträge übernommen.
               }

          PHP kennt ein Feature namens Magic Quotes. Das macht das, was wir oben mit dem mysql_real_escape_string() gemacht haben automatisch mit sämtlichen Eingabedaten. Und das ist nicht gut. Diese Daten werden ja nicht in jedem Fall an eine Datenbank übergeben. Besonders bei der Affenformulartechnik drehen die Daten erstmal ein paar Runden zwischen Anwender und PHP, ohne dass dabei eine Datenbank im Spiel ist. Doch die Magic Quotes wirken bei jeder Runde und stören nur.

          Mit obigem Code erstellst du neue Variablen aus den Eingabewerten. Wenn M.Q. aktiviert sind, machst du dessen Auswirkungen rückgängig. Soweit so gut. Doch dieses Stück Code ist genau auf deine beiden derzeitigen Werte zugeschnitten. Wenn noch einer hinzukommt, musst du für alle Verzweigungen die gleiche Behandlung hinzufügen, nur mit anderen Variablennamen. Besser ist es, statt Einzelbehandlung und neuen Variablen eine generelle Behandlung vorzunehmen und die bereits bestehenden Strukturen ($_GET/$_POST) weiterzuverwenden. Das hat auch noch den Vorteil, dass man im weiteren Verlauf des Scripts anhand eines $_POST['vorname'] im Gegensatz zu $vorname sofort ansieht, dass die Daten vom Benutzer kommen (und ungeprüfte Werte enthalten).

          Im Kapitel Disabling Magic Quotes findest du ein Stück Code, das am Scriptanfang eingebunden werden kann und sollte, und das die M.Q. direkt in den $_POST- usw. -Arrays entfernt. Wenn dann irgendwann PHP6 erschienen ist, und M.Q. endgültig gestorben sind, muss nur noch dieses Stück entfernt werden, und weiter läuft dein Script, ohne weitere Umbauarbeiten.

          Leider krankt diese Tutorialseite an den altbekannten Anfängerunsitten und -fehlern. Zum einen ist da das übliche unsinnige Umkopieren der Eingabewerte in andere Variablen enthalten, und zum anderen fehlt die kontextgerechte Behandlung der Werte, die unter anderem auch dem Schutz gegenüber SQL-Injection dient.
          Schade, das war eines der wenigen Dinge, die ich verstanden habe. *seufz*

          Vielleicht weißt du ja jetzt, was dort und warum beanstandenswert ist.

          echo "$verabschiedung $name";