AndyFFM: Fehlerhafter Eintrag eines Select-Feldes mittels MySQL Update

Hallo,
für mich scheinbar aus dem Nichts ist plötzlich ein Fehler in meinem Code, der ohne bewusste Änderung vorher fehlerfrei funktionierte.

Ich lasse aus einem Formular mittels $_POST aus einem Select-Feld das Geschlecht einer Person übergeben. Der Value ist entweder "w" oder "m".

Zur Fehlerquellensuche lasse ich ausgeben:
echo "Übergebenes Geschlecht:".$_POST['geschlecht'];

Die Ausgabe zeigt immer korrekt w oder m an.

Dann lasse ich das in der Datenbank speichern mittels:

  
$sql= "UPDATE profil SET Geschlecht = '".$_POST['geschlecht']."' WHERE Name = '".$_SESSION['ID']."';";  
$result = mysql_query($sql) OR die(mysql_error());  

Nun tritt der Fehler auf, dass er in der Datenbank nichts speichert. Auch wenn dort vorher z.B. der Wert "m" eingetragen war, überschreibt er ihn nun mit einem leeren Feld.

Wenn ich im $sql-String statt '".$_POST['geschlecht']."' einen manuellen String eintrage wie 'xytest', wird dieser korrekt gespeichert.

Auch wenn ich eine Übergangsvariable benutze wie

  
$geschlecht = $_POST['geschlecht'];  
$sql= "UPDATE profil SET Geschlecht = '".$geschlecht."' WHERE Name = '".$_SESSION['ID']."';";  

wird ein leeres Feld gespeichert. Wenn ich die Variable manuell auf $geschlecht = "test" setze, wird korrekt "test" gespeichert.

Ich habe nachgelesen, dass per $_POST übergebene Werte immer Strings sind, was mir auch in den Kram passt. Bloß warum funktionieren manuelle String im Update, der String aus der $_POST-Variable jedoch nicht?

Ich hoffe jemand sieht den Fehler. Danke für Hilfe :)
Andy

  1. fixer Nachtrag.

    Ich habe im Code, der die $_POST-Daten empfängt, eine Zeile, die ich irgendwo rauskopiert habe und nicht hundertprozentig verstehe, aber ob sie im Code ist oder auskommentiert ist, macht im Ergebnis keinen Unterschied

    $_POST = get_magic_quotes_gpc() ? array_map( 'stripslashes', $_POST ) : $_POST;

    Ebenso wurde ursprünglich mit

      
    $sql= "UPDATE profil SET Geschlecht = '".mysql_real_escape_string($_POST['geschlecht'])."' WHERE Name = '".$_SESSION['ID']."';";  
    
    

    gespeichert. Aber ob mysql_real_escape_string() benutzt wird oder nicht, macht für das fehlerhafte Ergebnis ebenfalls keinen Unterschied.

    Grüße

  2. Ich hoffe jemand sieht den Fehler. Danke für Hilfe :)

    Den siehst du, wenn du dir mal zum Testen deinen SQL String ausgeben lässt ;)

    --
    ie:{ br: fl:( va:) ls:& fo:| rl:( n4:( de:] ss:) ch:| js:| mo:| sh:( zu:)
    1. Ich hoffe jemand sieht den Fehler. Danke für Hilfe :)
      Den siehst du, wenn du dir mal zum Testen deinen SQL String ausgeben lässt ;)

      Hab ich grad gemacht, aber sehe den Fehler leider nicht. Ausgabe ist:
      UPDATE profil SET Geschlecht = 'm' WHERE Name = 'Beispielname';

      Und in der Datenbank wird ein leeres Feld gespeichert.
      Ich habs gleich ein zweites Mal probiert und statt der $_POST-Variable, die "m" beinhaltet, manuell 'm' in den SQL-String geschrieben und die Ausgabe des SQL-Strings ist ebenfalls:

      UPDATE profil SET Geschlecht = 'm' WHERE Name = 'Beispielname';

      bloß: JETZT speichert er korrekt "m" in der Datenbank. Das kann doch irgendwie nicht sein. Gibt es verschiedene Arten von Strings, die inkompatibel sind oder sowas? oO

      1. bloß: JETZT speichert er korrekt "m" in der Datenbank. Das kann doch irgendwie nicht sein. Gibt es verschiedene Arten von Strings, die inkompatibel sind oder sowas? oO

        mal ein tipp: gib mal beide Varianten mit var_dump aus und kontrollier dann (vielleicht haben sie eine andere Länge?) und dann probierst du den generierten String mal mit phpMyAdmin aus oder so...

        --
        ie:{ br: fl:( va:) ls:& fo:| rl:( n4:( de:] ss:) ch:| js:| mo:| sh:( zu:)
        1. mal ein tipp: gib mal beide Varianten mit var_dump aus und kontrollier dann (vielleicht haben sie eine andere Länge?) und dann probierst du den generierten String mal mit phpMyAdmin aus oder so...

          var_dump gibt bei beiden Varianten identisch
               string(57) "UPDATE profil SET Geschlecht = 'm' WHERE Name = 'Beispielname';"
          aus.

          Der generierte String in phpMyAdmin eingegeben trägt auch "m" korrekt ein, weils ja quasi identisch zu dem Fall ist, wie wenn ich das "m" schon manuell in den Query im Code schreibe und nicht durch eine $_POST-Variable übergeben lasse.

          1. Dann poste mal bitte den kompletten Code :)

            --
            ie:{ br: fl:( va:) ls:& fo:| rl:( n4:( de:] ss:) ch:| js:| mo:| sh:( zu:)
            1. Hi!

              Dann poste mal bitte den kompletten Code :)

              Nein! Bitte den Code soweit reduzieren, dass das Problem grade noch zu sehen ist.

              Lo!

              1. So als Info, falls es euch interessiert. Das Problem hat sich jetzt gelöst, wenn auch irgendwie nicht ganz für die Neugier befriedigend. In einem verzweifelten Schuß in den Wald hab ich nach und nach verschieden andere Teil der Seite nicht mitausführen lassen und plötzlich ging das Speichern in der Datenbank wieder korrekt. Ich hab den fehler lokalisiert auf eine Stelle, wo eine Liste angezeigt wird, welche Leute sich gerade auf der Seite eingeloggt haben. Neben den Leuten wird ein kleines .gif angezeigt mit einem Männlich- oder Weiblich-Symbol.
                Das speichern ging plötzlich als ich den Code umgeschrieben hab zu etwa in der Art (ist jetzt aus dem Gedächtnis, vielleicht fehlt mal eine Klammer oder so)

                if($row['Geschlecht']=="m"){
                  echo "<img src="male.gif">";
                }else{
                  echo "<img src="female.gif">";
                }

                der FEHLERHAFTE Code vorher hingegen sah so aus:

                echo "<img src="";
                if($row['Geschlecht']=="m"){
                  echo "male.gif";
                }else{
                  echo "female.gif";
                }
                echo "">";

                Ich weiß, sieht nicht grade sauber aus. Wie sich das auf den MySQL-Query duzente Codezeilen später auswirken kann und woher der Unterschied zwischen 'm' und $_POST['Geschlecht'] //(='m')
                kam, ist mir nach wie vor ein Rätsel.
                Aber nagut, wenigstens gehts jetzt wieder und ich musste mich nicht in die Klapse einweisen lassen. :) Vielleicht frag ich mal das Galileo Mystery-Team.

                Jedenfalls vielen Danke für eure Hilfsbereichtschaft. Ein paar nützliche Ansätze zur Fehlerbehebung bei kommenden Problemen hab ich immerhin gelernt :)

                1. Hi!

                  if($row['Geschlecht']=="m"){
                    echo "<img src="male.gif">";
                  }else{
                    echo "<img src="female.gif">";
                  }

                  der FEHLERHAFTE Code vorher hingegen sah so aus:

                  echo "<img src="";
                  if($row['Geschlecht']=="m"){
                    echo "male.gif";
                  }else{
                    echo "female.gif";
                  }
                  echo "">";

                  Funktional nehmen sich beide nichts, wenn ich nicht grad etwas übersehe oder du deinen Fehler nicht mitkopiert hast.

                  Wie sich das auf den MySQL-Query duzente Codezeilen später auswirken kann und woher der Unterschied zwischen 'm' und $_POST['Geschlecht'] //(='m') kam, ist mir nach wie vor ein Rätsel.

                  Das Problem wird vermutlich gewesen sein, dass du einen Verweis auf "" erzeugt hast, was den Browser veranlasst hat, einen Request auf die gleiche Ressource auszuführen, diesmal aber ohne POST-Daten. Desweiteren wirst du davon ausgegangen sein, dass diese Ressource nur per POST aufgerufen wird, weswegen du bei einem GET-Aufruf diesen nicht richtig abfängst. In POST stehen dann keine Werte, die dann natürlich den eben eingefügten Eintrag in der Datenbank überschreiben.

                  Durch das Entfernen der anderen, für das Problem scheinbar nicht relevanten Codeteile, hast du auch die eigentliche Ursache erwischt. Beim Reduzieren des Problems auf den geringstmöglichen Code, kann sich genau das ergeben, dass der Fehler beim Entfernen "unbeteiligten" Codes mit verschwindet und sich damit zeigt, dass die Ursache eigentlich ganz woanders lag. Das zeigt aber auch, dass deine zunächst betrachtete Codestelle Schwachstellen hat, weil du nicht ausreichend prüfst, ob das was du bekommst, deinen Erwartungen entspricht.

                  Wenn meine Vermutung so richtig ist, hättest du das durch die Auswertung der Requests des Browsers sehen sollen. Du siehst es nicht durch Kontrollausgaben, weil du ja nur die vom Hauptrequest anschaust, nicht aber die vom zweiten Request. Es sei denn, du schreibst die Kontrollausgaben in eine Datei (inklusive ordentlichem File Locking).

                  Lo!

      2. Hi!

        Hab ich grad gemacht, aber sehe den Fehler leider nicht. Ausgabe ist:
        UPDATE profil SET Geschlecht = 'm' WHERE Name = 'Beispielname';
        Und in der Datenbank wird ein leeres Feld gespeichert.

        Lass bei diesem Versuch einmal die livehttpheaders-Extension für den Firefox mitschneiden, was zwischen Client und Server für Requests ausgetauscht werden. Möglicherweise gibt es einen zweiten Request, der dein Messergebnis wieder zunichte macht. Alternativ kannst du natürlich auch ins Access-Log deines Webservers schauen.

        Lo!

        1. Lass bei diesem Versuch einmal die livehttpheaders-Extension für den Firefox mitschneiden, was zwischen Client und Server für Requests ausgetauscht werden. Möglicherweise gibt es einen zweiten Request, der dein Messergebnis wieder zunichte macht. Alternativ kannst du natürlich auch ins Access-Log deines Webservers schauen.
          Lo!

          livehttpheads kannte ich noch nicht, aber hab mir das so genannte Addon für Firefox grad installiert. Ich vermute dein Hinweis geht auf den Reiter "Generator" und die Anzeige nach "Fehlerhaft" filtern zu lassen?
          So getan und dort erscheint die Zeile
          "POST /index.php?section=editprofile&card=memberhome geschlecht=m&submit=Abschicken"

          Könnte das Leerzeichen vor "geschlecht" der Fehler sein? Wenn ja, wie kriege ich Zugriff darauf?

          Zusatz:
          Ich hab die ganze Sache grade unter vier Browsern getestet.
          Wenn ich die $_POST-Variable in den Query schreib, führen Opera10 und IE8 die Sache korrekt aus und es steht das Geschlecht "m" in der Datenbank, so wie es sein soll. Bei Firefox3 und Chrome3 wird ein leeres Feld in der Datenbank gespeichert.

          Ich hab auch noch mal sichergestellt, dass die Variable, die den Query-String beinhaltet, eindeutig ist und nicht ausversehen an einer anderen Stelle nochmals aufgerufen wird und dort evtl. den vorherigen korrekten Eintrag sofort wieder leer überschreibt, wie du hingewiesen hattest. Fehler bleibt leider.

          Ob ich auf den Access-Log meines Webservers Zugriff habe, weiß ich grad gar nicht. Im Logs-Verzeichnis befindet sich nur dieses awstats, das täglich nachts aktualisiert wird. Soll ich dem mal genauer nachgehn oder bin ich mit dem livehttpheaders eh schon an der richtigen Stelle gewesen?

          Danke und Grüße

          1. Hi!

            livehttpheads kannte ich noch nicht, aber hab mir das so genannte Addon für Firefox grad installiert. Ich vermute dein Hinweis geht auf den Reiter "Generator" und die Anzeige nach "Fehlerhaft" filtern zu lassen?

            Lass alles so wie es ist. Es soll alles mitgeschrieben werden. Schau dann, wonach requestet wird. Du könntest höchstens über "Konfiguration" den Wert für POST auf "Genau" stellen.

            So getan und dort erscheint die Zeile
            "POST /index.php?section=editprofile&card=memberhome geschlecht=m&submit=Abschicken"

            Könnte das Leerzeichen vor "geschlecht" der Fehler sein? Wenn ja, wie kriege ich Zugriff darauf?

            Wer löst diesen Request aus? Du beim Drücken des Submittbuttons eines einfachen Formulars oder spielt da auch noch Javascript mit? Ist der HTML-Code für das Formular in Ordnung - also so wie es der Browser sieht, sprich: in seiner Quelltextansicht? (Ist es notwendig, dass der POST-Request jede Menge Parameter im Querystring (=GET-Parameter) mitsendet?)

            Ob ich auf den Access-Log meines Webservers Zugriff habe, weiß ich grad gar nicht. Im Logs-Verzeichnis befindet sich nur dieses awstats, das täglich nachts aktualisiert wird. Soll ich dem mal genauer nachgehn oder bin ich mit dem livehttpheaders eh schon an der richtigen Stelle gewesen?

            Schau erst einmal in das vollständige Log der livehttpheaders-Extension.

            Lo!