Yadgar: Kollationsproblem bei MySQL?

Hi(gh)!

Ich habe in meinem aktuellen Datenbank-Projekt (29 Tabellen) in sämtlichen Tabellen die Kollation utf8_general_ci verwendet. Wenn ich jetzt in einem varchar-Feld ein Hochkomma ' eingebe, erscheint es sowohl  bei der Anzeige des Tabelleninhalts mittels PHPMyAdmin als auch in den Pulldown-Auswahlmenüs meiner selbst programmierten Eingabemaske als ' (letzteres gilt auch, wenn ich nachträglich "manuell" über PHPMyAdmit das ' nach ' korrigiere!). Wenn ich nun dieser Eingabemaske einen Eintrag mit ' auswähle und die damit verbundene ID-Zahl (Primärschlüssel) in eine Relationstabelle (n-m-Beziehung) übertragen will, hängt sich MySQL in einer Endlosschleife auf und bricht nach 60 Sekunden mit einem Fatal Error ab. Liegt es an der falschen Kollation? Oder steckt der Fehler in der PHP-Programmierung der Eingabemaske?

Hier die Zeile, in der die Endlosschleife auftritt:

  
while ($row == mysql_fetch_row($result)) // nur 1 Ergebniszeile!  
          $ids[0]=$row[0];  

Wenn ich mir testhalber den Inhalt von $result mit print_r() anzeigen lasse, bekomme ich nur "Resource id#8", nicht etwa die ID-Zahl der abgefragten Tabellenzeile...

Bis bald im Khyberspace!

Yadgar

  1. Moin!

    Ich habe in meinem aktuellen Datenbank-Projekt (29 Tabellen) in sämtlichen Tabellen die Kollation utf8_general_ci verwendet. Wenn ich jetzt in einem varchar-Feld ein Hochkomma ' eingebe, erscheint es sowohl  bei der Anzeige des Tabelleninhalts mittels PHPMyAdmin als auch in den Pulldown-Auswahlmenüs meiner selbst programmierten Eingabemaske als '

    PHP magic quotes.

    (letzteres gilt auch, wenn ich nachträglich "manuell" über PHPMyAdmit das ' nach ' korrigiere!).

    Userfehler oder Cache. ;)

    Wenn ich nun dieser Eingabemaske einen Eintrag mit ' auswähle und die damit verbundene ID-Zahl (Primärschlüssel) in eine Relationstabelle (n-m-Beziehung) übertragen will, hängt sich MySQL in einer Endlosschleife auf und bricht nach 60 Sekunden mit einem Fatal Error ab. Liegt es an der falschen Kollation? Oder steckt der Fehler in der PHP-Programmierung der Eingabemaske?

    Sicherlich ist irgendwas kaputt. Eigener Code ist der erste Verdächtige.

    Hier die Zeile, in der die Endlosschleife auftritt:

    while ($row == mysql_fetch_row($result)) // nur 1 Ergebniszeile!
              $ids[0]=$row[0];

    
    >   
    > Wenn ich mir testhalber den Inhalt von $result mit print\_r() anzeigen lasse, bekomme ich nur "Resource id#8", nicht etwa die ID-Zahl der abgefragten Tabellenzeile...  
      
    Das ist vollkommen normal, Resultate einer DB-Abfrage sind Ressourcen - es sind "Pointer" auf Speicherbereiche, in denen das bereits von der Datenbank abgeholte Ergebnis zur Abfrage mit z.B. mysql\_fetch\_row() bereitliegt.  
      
    Entscheidend ist das Debugging vorher: Welcher String kommt aus dem Formularfeld in $\_POST an? Und welches Ergebnis hat `get_magic_quotes_gpc()`{:.language-php}?  
      
     - Sven Rautenberg
    
    1. Hi(gh)!

      [quote="Sven Rautenberg"]

      PHP magic quotes.

      [/quote]

      Ich habe in der php.ini nachgesehen, magic_quotes_gpc auf Off gesetzt, MySQL und den Apachen angehalten, neu gestartet... aber ich bekomme immer noch den Fatal Error nach 60 Sekunden! Der einzige Weg, das zu verhindern, ist vor dem Absenden der MySQL-Abfrage mit stripslashes() die Slashes aus den POST-Daten zu entfernen... irgendwie suboptimal!

      Bis bald im Khyberspace!

      Yadgar

      1. Moin!

        Hi(gh)!

        [quote="Sven Rautenberg"]

        PHP magic quotes.
        [/quote]

        Ich habe in der php.ini nachgesehen, magic_quotes_gpc auf Off gesetzt, MySQL und den Apachen angehalten, neu gestartet... aber ich bekomme immer noch den Fatal Error nach 60 Sekunden! Der einzige Weg, das zu verhindern, ist vor dem Absenden der MySQL-Abfrage mit stripslashes() die Slashes aus den POST-Daten zu entfernen... irgendwie suboptimal!

        Das liegt an deinem Query. Seh' ich von hier.

        - Sven Rautenberg

        1. Hi(gh)!

          Das liegt an deinem Query. Seh' ich von hier.

          Ich leider nicht... und als wäre das noch nicht genug, tritt gleich das nächste Problem auf:
          egal, ob magic_quote_gpc() auf Off gesetzt ist oder nicht, $Titel wird nie als titel.Name gefunden, in die Relationstabelle wird folglich immer 0 eingetragen! Wenn ich dagegen in PHPMyAdmin im SQL-Menü z. B. eingebe

          SELECT ID FROM titel WHERE Name="I Saw You Standing There";

          wird die korrekte ID-Nummer angezeigt! Läuft mit mysql_real_escape_string() irgendwas falsch, und wenn ja, warum?

          Hier nochmal der Code im Kontext:

            
          $query= "SELECT ID FROM titel WHERE Name='".mysql_real_escape_string($Titel)."'";  
          $result = mysql_query($query);  
          dberror();  
          while ($row == mysql_fetch_row($result)) // nur 1 Ergebniszeile!  
            $ids[0]=$row[0];  
          $query= "SELECT ID FROM veroeffentlichung WHERE Name='".mysql_real_escape_string($Veroeffentlichung)."'";  
          $result = mysql_query($query);  
          dberror();  
          while ($row = mysql_fetch_row($result)) // nur 1 Ergebniszeile!  
            $ids[1]=$row[0];				  
          					  
          $query = "INSERT INTO titel_veroeffentlichung (Titel, Veroeffentlichung, Seite, Position) VALUES ('".mysql_real_escape_string($ids[0])."','".mysql_real_escape_string($ids[1])."','".mysql_real_escape_string($Seite)."','".mysql_real_escape_string($Position)."')";  
          $result = mysql_query($query);  
          dberror();  
          echo "Ihre Eingabe war korrekt und wurde in die Datenbank eingetragen!";  
          
          

          Die zweite Query wird übrigens korrekt verarbeitet... das verstehe wer will, ich jedenfalls nicht... ich bin wohl zu dumm zum Programmieren!

          Bis bald im Khyberspace!

          Yadgar

          1. Moin!

            Hier nochmal der Code im Kontext:

            Das ist super, den hast du bislang verheimlicht!

            echo "<pre>";
            var_dump($Titel);
            var_dump($Veroeffentlichung);

            $query= "SELECT ID FROM titel WHERE Name='".mysql_real_escape_string($Titel)."'";

            var_dump($query);

            $result = mysql_query($query);
            dberror();
            while ($row == mysql_fetch_row($result)) // nur 1 Ergebniszeile!
              $ids[0]=$row[0];
            $query= "SELECT ID FROM veroeffentlichung WHERE Name='".mysql_real_escape_string($Veroeffentlichung)."'";

            var_dump($query);

            $result = mysql_query($query);
            dberror();
            while ($row = mysql_fetch_row($result)) // nur 1 Ergebniszeile!
              $ids[1]=$row[0];

            var_dump($ids);

            $query = "INSERT INTO titel_veroeffentlichung (Titel, Veroeffentlichung, Seite, Position) VALUES ('".mysql_real_escape_string($ids[0])."','".mysql_real_escape_string($ids[1])."','".mysql_real_escape_string($Seite)."','".mysql_real_escape_string($Position)."')";

            var_dump($query);

            $result = mysql_query($query);

            dberror();
            echo "Ihre Eingabe war korrekt und wurde in die Datenbank eingetragen!";

            
            >   
            > Die zweite Query wird übrigens korrekt verarbeitet... das verstehe wer will, ich jedenfalls nicht... ich bin wohl zu dumm zum Programmieren!  
              
            Debugging und Fehleranalyse gehört jedenfalls dazu, und das ist im Moment noch schwach.  
              
            Bleibt die Frage: Warum suchst du zu den Texten, die anscheinend in der DB schon existieren, immer noch mal die ID separat raus? Häng die ID doch im SELECT als value an die Option ran und verwende sie direkt, ohne Suchen. (Und an dieser Stelle dürfen sich andere Teilnehmer des Forums dann dem Thema Validierung und Nebenläufigkeit widmen, wenn sie wollen.)  
              
             - Sven Rautenberg
            
          2. Tach!

            while ($row == mysql_fetch_row($result)) // nur 1 Ergebniszeile!
              $ids[0]=$row[0];

            Das ist die Ursache für deinen Timeout. Du hast dir hier eine Endlosschleife gebaut, die dann endlos wird, wenn kein Ergebnis gefunden werden konnte. == ist ein Vergleichsoperator. $row ist allem Anschein nach vorher nicht vorhanden, also wird es beim Lesen zu null (und erzeugt gleich noch eine Notice, die man angezeigt bekäme, stünde das error_reporting auf E_ALL sowie display_errors auf on). mysql_fetch_row() liefert false, null == false ergibt true und das bei jedem Durchlauf. Wenn doch ein Ergebnis abgefragt werden konnte, ergibt die zweite Zeile ebenfalls nur eine Notice, denn $row ist immer noch null und kein Array. Eine Debugausgabe (mit var_dump()) hätte hier auch gezeigt, dass in $row nicht das gewünschte Ergebnis steht.

            while ($row = mysql_fetch_row($result)) // nur 1 Ergebniszeile!
            Die zweite Query wird übrigens korrekt verarbeitet...

            Ja, hier ist ja auch eine Zuweisung notiert, so wie man das üblicherweise macht.

            dedlfix.

            1. Hi(gh)!

              while ($row == mysql_fetch_row($result)) // nur 1 Ergebniszeile!
                $ids[0]=$row[0];

              Das ist die Ursache für deinen Timeout. Du hast dir hier eine Endlosschleife gebaut, die dann endlos wird, wenn kein Ergebnis gefunden werden konnte. == ist ein Vergleichsoperator. $row ist allem Anschein nach vorher nicht vorhanden, also wird es beim Lesen zu null (und erzeugt gleich noch eine Notice, die man angezeigt bekäme, stünde das error_reporting auf E_ALL sowie display_errors auf on). mysql_fetch_row() liefert false, null == false ergibt true und das bei jedem Durchlauf. Wenn doch ein Ergebnis abgefragt werden konnte, ergibt die zweite Zeile ebenfalls nur eine Notice, denn $row ist immer noch null und kein Array. Eine Debugausgabe (mit var_dump()) hätte hier auch gezeigt, dass in $row nicht das gewünschte Ergebnis steht.

              while ($row = mysql_fetch_row($result)) // nur 1 Ergebniszeile!
              Die zweite Query wird übrigens korrekt verarbeitet...

              Ja, hier ist ja auch eine Zuweisung notiert, so wie man das üblicherweise macht.

              Das leuchtet mir ein - ich habe den Vergleichsoperator bei der ersten Query durch den Zuweisungsoperator ersetzt, und jetzt funktioniert es korrekt! Danke für den Tipp! Ein Problem (wenn auch nicht akut) bleibt jedoch: enthält $Titel an irgendeiner Stelle ein ', dann wird der String in der Query nur gefunden, wenn ich vorher mit stripslashes() den Magic-Quote-Slash entfernt habe... und das, obwohl ich in der php.ini magic_quotes_gpc() auf Off gesetzt habe! Sollten dann nicht erst gar keine Magic Quotes erzeugt werden?

              Bis bald im Khyberspace!

              Yadgar

              1. Tach!

                Ein Problem (wenn auch nicht akut) bleibt jedoch: enthält $Titel an irgendeiner Stelle ein ', dann wird der String in der Query nur gefunden, wenn ich vorher mit stripslashes() den Magic-Quote-Slash entfernt habe... und das, obwohl ich in der php.ini magic_quotes_gpc() auf Off gesetzt habe! Sollten dann nicht erst gar keine Magic Quotes erzeugt werden?

                Ein Aufruf von phpinfo() sagt dir einerseits, welche php.ini-Datei(en) gelesen wurden und andererseits, wie der Wert gerade eingestellt ist. In der php.ini wird der Wert überigens ohne ()-Klammern geschrieben, es ist dort ja keine Funktion.

                dedlfix.