Simon: $ergebnis->bind_result alle Variablen sind leer

Hi, bin grad dabei mich etwas in mysqli einzuarbeiten.

$db = new mysqli($dbhost, $dbuser, $dbpass, $dbname);  
if (mysqli_connect_errno() == 1)  
{  
  die('Die Datenbank konnte nicht erreicht werden. Folgender Fehler trat auf: <strong>'.mysqli_connect_errno().':'.mysqli_connect_error().'</strong>');  
}  
$sql = 'SELECT  
          `Vorname`,  
          `Nachname`,  
        FROM  
          `Tabelle`  
        WHERE  
          UserId ='.$UserId.'';  
$ergebnis = $db->prepare($sql);  
$ergebnis->execute();  
$ergebnis->bind_result($Vorname, $Nachname);

Ich wollte jetzt $Vorname und $Nachname ausgeben nur sind beide leer und ich weiß wirklich nicht an was das liegen kann. Die Variable $UserId hat einen Wert, also kann es denk ich nicht an dem liegen.

Ist vielleicht am Beispiel oben was falsch?

MfG
Simon

  1. Hi,

    Hi, bin grad dabei mich etwas in mysqli einzuarbeiten.

    $sql = 'SELECT
              Vorname,
              Nachname,
            FROM
              Tabelle
            WHERE
              UserId ='.$UserId.'';

    Warum setzt du hier den Wert direkt in Textform ein?
    Wenn du schon MySQLi und prepared statements nutzt, warum dann nicht richtig? (Platzhalter in Query, und dann bind_param.)

    $ergebnis = $db->prepare($sql);
    $ergebnis->execute();
    $ergebnis->bind_result($Vorname, $Nachname);[/code]

    Füge hier eine sinnvolle Fehlerauswertung ein.

    MfG ChrisB

    --
    “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
    1. $sql = 'SELECT
               Vorname,
               Nachname,
             FROM
                Tabelle
             WHERE
                 UserId =(?)';
      $ergebnis = $db->prepare($sql);
      $ergebnis->bind_param('s',$UserId);
      $ergebnis->execute();
      $ergebnis->bind_result($Vorname, $Nachname);

      meinst du so?

      1. Hi!

        $sql = 'SELECT
                 Vorname,
                 Nachname,
               FROM
                  Tabelle
               WHERE
                   UserId =(?)';

        Die Klammer um den Platzhalter kann weg.

        $ergebnis = $db->prepare($sql);

        Nebenbei: Der Name $ergebnis ist irreführend, weil ein Prepared Statement noch kein Ergebnis darstellt.

        $ergebnis->bind_param('s',$UserId);
        $ergebnis->execute();
        $ergebnis->bind_result($Vorname, $Nachname);

        So sieht das schon etwas besser aus. Allerdings hast du immer noch keine Fehlerbehandlung eingebaut. Schau im PHP-Handbuch nach, was die Methoden im Fehlerfall liefern und prüfe vor dem Fortsetzen, ob nicht solch ein Fehlerwert geliefert wurde.

        Außerdem wäre der Handbuch-Blick (beispielsweise für bind_result()) auch für dein Problem von Nutzen gewesen, denn dann wäre dir beim Lesen der dortigen Hinweise vielleicht aufgefallen, dass du vergessen hast, eine weitere Methode aufzurufen.

        Lo!

        1. So sieht das schon etwas besser aus. Allerdings hast du immer noch keine Fehlerbehandlung eingebaut. Schau im PHP-Handbuch nach, was die Methoden im Fehlerfall liefern und prüfe vor dem Fortsetzen, ob nicht solch ein Fehlerwert geliefert wurde.

          Wäre es ausreichend mit:
          printf("Error: %d.\n", $ergebnis->errno);  ??

          Außerdem wäre der Handbuch-Blick (beispielsweise für bind_result()) auch für dein Problem von Nutzen gewesen, denn dann wäre dir beim Lesen der dortigen Hinweise vielleicht aufgefallen, dass du vergessen hast, eine weitere Methode aufzurufen.

          Stimmt hab ich ganz übersehen ->fetch();
          Aber "2 hours of try and error can save 10 minutes of manual reading"
          nur waren es halt bei mir leider mehr als 2 Stunden ^^

          MfG
          Simon

          1. Was ich noch vergessen hab:
            mein Script is jetzt ca. so aufgebaut:

            $db = new mysqli($dbhost, $dbuser, $dbpass, $dbname);  
            if (mysqli_connect_errno() == 1)  
            {  
              die('Die Datenbank konnte nicht erreicht werden. Folgender Fehler trat auf: <strong>'.mysqli_connect_errno().':'.mysqli_connect_error().'</strong>');  
            }  
              
            $sql = ' bla bla bla';  
            $ergebnis = $db->prepare($sql);  
            $ergebnis->bind_param('s',$UserId);  
            $ergebnis->execute();  
            $ergebnis->bind_result(bla bla bla);  
            $ergebnis->fetch();  
            $ergebnis->close();  
              
            $sql = 'bla bla bla';  
            $ergebnis = $db->prepare($sql);  
            $ergebnis->bind_param('s',$Klasse);  
            $ergebnis->execute();  
            $ergebnis->bind_result(bla bla bla);  
            $ergebnis->fetch();  
            
            

            Ich bekomm hier aber diese Fehlermeldung:
            Fatal error: Call to a member function bind_param() on a non-object
            also auf das bind_param() in der zweiten Abfrage.

            muss ich nach der ersten Abfrage noch was machen oder reicht es mit
            $ergebnis->close(); ??

            MfG
            Simoni

            1. Hi!

              $ergebnis = $db->prepare($sql);
              $ergebnis->bind_param('s',$Klasse);
              Ich bekomm hier aber diese Fehlermeldung:
              Fatal error: Call to a member function bind_param() on a non-object
              also auf das bind_param() in der zweiten Abfrage.

              Genau das meinte ich mit Fehlerbehandlung (oder auch robuster Programmierung genannt). mysli::prepare() liefert etwas zurück, dass einmal ein mysqli_stmt-Objekt sein kann, aber auch false, wenn ein Fehler auftritt. Du prüfst das nicht und verwendest $ergebnis einfach so, als ob immer alles in bester Ordnung ist. Die Folge ist der Folgefehler, den du da siehst. Die eigentliche Ursache bekommst du durch Auswertung von mysqli::error (in deinem Fall $db->error).

              Schau dir das Beispiel zu mysqli::prepare(), da ist zumindest schon mal das weitere Arbeiten mit dem Statement-Objekt vom Rückgabewert abhängig gemacht worden.

              muss ich nach der ersten Abfrage noch was machen oder reicht es mit
              $ergebnis->close(); ??

              Das wäre eine Möglichkeit. Wie das Handbuch zu mysli_stmt::close() mitteilt, werden dabei alle "pending and unread results" verworfen, so dass du das nächste Statement ausführen kannst. Alternativ - siehe Hinweis mysqli_stmt::fetch() kannst du auch mysli_stmt::store_result() aufrufen, um das Ergebnis vom Server abzuholen und lokal puffern zu lassen. Das ist vor allem dann nötig, wenn man während des Fetch-Vorgangs weitere Statements absetzen will (was man aber meist eine unperformante Idee ist).

              Die eigentliche Frage ist aber: warum fragst du das DBMS nach Dingen, die du am Ende doch gar nicht wissen willst?

              Lo!

              1. Hi!

                Die Folge ist der Folgefehler, den du da siehst. Die eigentliche Ursache bekommst du durch Auswertung von mysqli::error (in deinem Fall $db->error).

                Es kann aber auch sein, dass eine PHP-Warnung kommt (Warning:  mysqli::prepare(): All data must be fetched before a new statement prepare takes place), die angezeigt werden müsste, wenn das error_reporting ausreichend konfiguriert ist (E_ALL ist beim Entwickeln immer eine gute Idee - und display_errors sollte auch auf on stehen).

                Lo!

                1. Es kann aber auch sein, dass eine PHP-Warnung kommt (Warning:  mysqli::prepare(): All data must be fetched before a new statement prepare takes place), die angezeigt werden müsste, wenn das error_reporting ausreichend konfiguriert ist (E_ALL ist beim Entwickeln immer eine gute Idee - und display_errors sollte auch auf on stehen).

                  Ok, jetzt scheint das ganze zu funktionieren.
                  Das error_reporting hab ich so:

                  <?php  
                  error_reporting(E_ALL);  
                  ini_set('display_errors', 1);  
                  ?>