Tobias: Seltsames verhalten bei mysql_fetch_object()

Hallo,
ich habe hier grad ein sehr merkwürdiges Problem. Mit folgendem Code realisiere ich einen Login in:

  
$sql="SELECT * FROM user WHERE nick='".$_POST['nick']."' AND passwort='".$_POST['pass']."';";  
   $ergebnis=mysql_query($sql) or die(mysql_error());  
  
   if(mysql_fetch_object($ergebnis))  
   {while($row=mysql_fetch_object($ergebnis))  
     { $rang = $row->rang;  
     }  
     .  
     .  
     .  

Ist der user samt dem Passwort in der Datenbank vorhanden - sprich der Login ist korrekt - geht er in den if-Block. Bis hier hin klappt alles. Nun möchte ich aber aus der eben durchgeführten Datenbankabfrage noch etwas auslesen. Doch nun ist er aufeinmal der Meinung das in der while-Bedingung false zurückgeliefert wird. hä? Wie ist er dann zuvor in den if-Block gekommen?
Füge ich vor dem while nochmal einen mysql_query ein ist auf einmal alles schon. Aber noch mal die gleiche DB-Abfrage starten wäre doch Ressourcen verschwendung.

Was das noch seltsamer macht, ist der Fakt, dass ich den selben Code auf einer Unterseite verwende und dort klappt alles.

Irgendwelche Ideen?

Danke und Tschau

Tobias

--
http://www.tobiasklare.de
fo:) ch:? rl:( br:^ n4:° ie:{ mo:) va:| fl:) ss:| ls:<
Die Erklärung zum Selfcode findest du hier: http://emmanuel.dammerer.at/selfcode.html
Einen Decoder für den Selfcode findest du hier: http://peter.in-berlin.de/projekte/selfcode
  1. Hi,

    $sql="SELECT * FROM user WHERE nick='".$_POST['nick']."' AND passwort='".$_POST['pass']."';";

    that ist ziemlich bad. Vom Denglisch abgesehen hat die Selektierung pauschal aller Spalten außerhalb von Testfällen nichts verloren.

    Ist der user samt dem Passwort in der Datenbank vorhanden - sprich der Login ist korrekt - geht er in den if-Block. Bis hier hin klappt alles.

    Ja.

    Nun möchte ich aber aus der eben durchgeführten Datenbankabfrage noch etwas auslesen.

    Warum? Glaubst Du, dass es mehr als einen Eintrag mit dieser Name/Passwort-Kombination gibt?

    Doch nun ist er aufeinmal der Meinung das in der while-Bedingung false zurückgeliefert wird. hä?

    Es gibt den User halt nur ein Mal.

    Wie ist er dann zuvor in den if-Block gekommen?

    Indem er die Daten ausgelesen und erkannt hat, dass sie vorhanden sind.

    Füge ich vor dem while nochmal einen mysql_query ein ist auf einmal alles schon. Aber noch mal die gleiche DB-Abfrage starten wäre doch Ressourcen verschwendung.

    Ja.

    Was das noch seltsamer macht, ist der Fakt, dass ich den selben Code auf einer Unterseite verwende und dort klappt alles.

    Das ist in der Tat seltsam.

    Irgendwelche Ideen?

    Lies die Daten aus und _nutze sie_, anstatt sie auszulesen, zu verwerfen und zu glauben, es würde noch mehr Daten geben.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
  2. hi,

    Ist der user samt dem Passwort in der Datenbank vorhanden

    Dann dürfte deine Abfrage genau einen Ergebnisdatensatz liefern, oder?

    sprich der Login ist korrekt - geht er in den if-Block.

    Du hast schon einmal mysql_fetch_object ausgeführt, um das festzustellen.
    Also, wo steht der interne "Zeiger" in der Ergebnismenge jetzt ...?

    Nun möchte ich aber aus der eben durchgeführten Datenbankabfrage noch etwas auslesen.
    Doch nun ist er aufeinmal der Meinung das in der while-Bedingung false zurückgeliefert wird. hä? Wie ist er dann zuvor in den if-Block gekommen?

    Natürlich, weil du hier jetzt zum zweiten mal fetchst.
    Wenn ein _zweiter_ Datensatz vorhanden wäre, würde dir das diesen liefern. Ist aber nicht ...

    Irgendwelche Ideen?

    Probier's mal mit etwas mehr Logik beim Programmieren ...

    Wenn du nur wissen willst, ob die Abfrage einen Ergebnisdatensatz lieferte - dann nutze mysql_num_rows().

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
  3. Hallo Tobias,

    ich habe hier grad ein sehr merkwürdiges Problem. Mit folgendem Code realisiere ich einen Login in:

    $sql="SELECT * FROM user WHERE nick='".$_POST['nick']."' AND passwort='".$_POST['pass']."';";

    Du solltest [link:http://www.php.net/manual/de/function.mysql-real-escape-string.php@title=mysql_real_escape_string()] auf Benutzereingaben anwenden, vorher in Abhängigkeit von der Konfiguration von magic quotes gpc [link:http://www.php.net/manual/de/function.stripslashes.php@title=stripslashes].

    $ergebnis=mysql_query($sql) or die(mysql_error());

    if(mysql_fetch_object($ergebnis))

    Hier rufst Du das erste Ergebnis Deiner Abfrage ab, sofern es überhaupt eines gibt. Den Inhalt dieses Ergebnisses wirfst Du weg.

    {while($row=mysql_fetch_object($ergebnis))

    Diese Anweisung weist im Erfolgsfall die zweite und in weiteren Durchläufen die folgenden Zeile Deiner Ergebnismenge der Variablen $row zu. In einem guten Loginsystem sollte die gleiche Kombination von Benutzernamen und Passwort nur einmal vorkommen. Wunderst Du Dich immer noch, dass Du hier nie das erhältst, was Du erwartest?

    
    > Irgendwelche Ideen?  
      
    Wirf das erste Ergebnis nicht weg, sondern weise es der Variablen $row zu. Überprüfe die Variable $row und arbeite im Erfolgfall mit dieser weiter. Auf Deine while-Schleife kannst Du getrost verzichten.  
      
      
    Freundliche Grüße  
      
    Vinzenz
    
  4. Ok,
    danke für eure Hilfe. Verwende jetzt mysql_real_escape_string in meiner if-Abfrage nutze ich mysql_num_rows(), die while Schleife ist beseitigt und SELECT ist auch eingegrenzt.

    Und das beste ist, es funktioniert alles.

    Nochmals danke.

    tschau

    Tobias

    1. Hi,

      danke für eure Hilfe. Verwende jetzt mysql_real_escape_string in meiner if-Abfrage nutze ich mysql_num_rows(), die while Schleife ist beseitigt und SELECT ist auch eingegrenzt.

      Und das beste ist, es funktioniert alles.

      Dennoch ist es m.E. ineffizient.
      Ich würde statt SELECT * FROM nur SELECT count(*) as anzahl FROM nutzen - Du willst ja schließlich die Anzahl wissen.

      Damit muß nur noch eine Zahl vom Datenbankserver nach PHP transportiert werden, nicht mehrere komplette Datensätze.

      cu,
      Andreas

      --
      Warum nennt sich Andreas hier MudGuard?
      Schreinerei Waechter
      Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
      1. echo $begrüßung;

        Dennoch ist es m.E. ineffizient.
        Ich würde statt SELECT * FROM nur SELECT count(*) as anzahl FROM nutzen - Du willst ja schließlich die Anzahl wissen.

        Damit muß nur noch eine Zahl vom Datenbankserver nach PHP transportiert werden, nicht mehrere komplette Datensätze.

        Es geht sogar noch weiter. Ich glaube, im MySQL-Handbuch gelesen zu haben, dass im Falle von count(*) auf eine einzelne Tabelle und ohne weitere WHERE-Klausel dieser Wert aus einer sowieso vorhandenen Statistik gelesen wird und keine "händische" Zählung erfolgt. Leider finde ich die Stelle grad nicht wieder.

        Ebenso entfällt natürlich die unnötige Bereitstellung der Datensätze der Ergebnismenge der Abfrage. Im Gegensatz zu mysql_unbuffered_query() holt nämlich mysql_query() das Ergebnis gleich auch noch vom MySQL-Server ab und puffert es zwischen. Die mysql_fetch_*-Funktionen fetchen also nach einem mysql_query() nicht direkt von der Datenbank sondern aus diesem Puffer.

        (Das generelle Umstellen auf mysql_unbuffered_query() aus Performancegründen ist aber auch nicht uneingeschränkt zu empfehlen. Die zu beachtenden Dinge stehen im Handbuch.)

        echo "$verabschiedung $name";

        1. Hi,

          Es geht sogar noch weiter. Ich glaube, im MySQL-Handbuch gelesen zu haben, dass im Falle von count(*) auf eine einzelne Tabelle und ohne weitere WHERE-Klausel dieser Wert aus einer sowieso vorhandenen Statistik gelesen wird und keine "händische" Zählung erfolgt.

          Dieser Fall trifft aber nicht zu, da ja nur die Datensätze mit dem passenden Usernamen/Paßwort selektiert werden.

          cu,
          Andreas

          --
          Warum nennt sich Andreas hier MudGuard?
          Schreinerei Waechter
          Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
      2. Hallo Andreas,

        danke für eure Hilfe. Verwende jetzt mysql_real_escape_string in meiner if-Abfrage nutze ich mysql_num_rows(), die while Schleife ist beseitigt und SELECT ist auch eingegrenzt.
        Und das beste ist, es funktioniert alles.

        Dennoch ist es m.E. ineffizient.
        Ich würde statt SELECT * FROM nur SELECT count(*) as anzahl FROM nutzen - Du willst ja schließlich die Anzahl wissen.

        wenn ich das Ausgangsposting lese, sehe ich das anders:

        $rang = $row->rang;

        Im Erfolgsfall (ein Datensatz) greift der OP somit auf die zurückgelieferten Daten zu. Sicherlich sollte der OP statt SELECT * FROM besser SELECT <kommagetrennte Feldliste> FROM verwenden. Es stimmt, er wurde nicht darauf hingewiesen.

        Damit muß nur noch eine Zahl vom Datenbankserver nach PHP transportiert werden, nicht mehrere komplette Datensätze.

        Wieso mehrere? Wir waren uns einig, dass das Ergebnis entweder aus einem Datensatz oder aus keinem besteht.

        Freundliche Grüße

        Vinzenz

        1. Hi,

          Wieso mehrere? Wir waren uns einig, dass das Ergebnis entweder aus einem Datensatz oder aus keinem besteht.

          Wenn es nur einen geben könnte, warum würde Tobias dann mit einer while-Schleife auf die Datensätze zugreifen wollen?

          cu,
          Andreas

          --
          Warum nennt sich Andreas hier MudGuard?
          Schreinerei Waechter
          Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
          1. Hallo Andreas,

            Wieso mehrere? Wir waren uns einig, dass das Ergebnis entweder aus einem Datensatz oder aus keinem besteht.

            Wenn es nur einen geben könnte, warum würde Tobias dann mit einer while-Schleife auf die Datensätze zugreifen wollen?

            Tobias hat diese doch bereits eliminiert, wie Du dem  Posting, das den Ausgangspunkt dieses Teilthreads bildet, entnehmen kannst. Inzwischen dürfte nur noch eine if-Anweisung übrig geblieben sein.

            Freundliche Grüße

            Vinzenz