wucher wichtel: + (PHP): mysqli_num_rows() erwartet Parameter?

Hallo!

Ich habe ein Problem mit folgendem Code:

  
<?php  
  
class Refer {  
  
  var $connection;  
  
  function Refer(){  
    $this->connection = mysqli_connect('localhost', 'root', 'XXXXXXX') OR die(mysql_error());  
    $this->login();  
  }  
  
  function checkUserData($name, $password){  
    $q = "SELECT  
            password  
          FROM  
            member  
          WHERE  
            name = '".$username."'";  
    $result = mysqli_query($this->connection, $q);  
    $row_cnt = mysqli_num_rows($result); # Das hier ist "Line 20" :)  
    return $row_cnt;  
  }  
  
  function login(){  
    $this->checkUserData("Hans");  
  }  
}  
  
$referTo = new Refer;  
  
?>  

Es kommt eine Fehlermeldung mit folgendem Inhalt:

#################################################
Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in D:\xampp\xampp\htdocs\test2.php on line 20
#################################################

Das kann ich mir nicht so richtig erklären. Das Beispiel auf php.net ist ähnlich gestrickt wie meins. Google hat mir auch nicht so richtig weitergeholfen.

Danke für eure Hilfe!

ciao, ww

--
Ein japanisch-deutsches Gedicht
sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
  1. Hallo,

    function checkUserData($name, $password){
        $q = "SELECT
                password
              FROM
                member
              WHERE
                name = '".$username."'";

    Ich zitiere Theo Lingen:
    Traurig, traurig, traurig.

    Solcher Code gehört verboten! Du liest doch hier recht viel mit.
    Warum arbeitest Du nicht mit mysqli_prepare,  bind_param(), und mysqli_stmt_execute() oder wenigstens mit mysqli_real_escape_string. Warum verwendest Du nicht den objektorientierten Ansatz, wenn Du schon versuchst, objektorientiert zu programmieren?

    $result = mysqli_query($this->connection, $q);

    Hm, hm. Was könnte wohl jetzt in $result stehen, wenn Du folgende Warnung erhältst?

    Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in D:\xampp\xampp\htdocs\test2.php on line 20

    Du übersiehst also die Möglichkeit, dass Deine Abfrage fehlschlägt. Du übersiehst die Möglichkeit, dass in $result _nicht_ vom Typ mysqli_result ist.

    Das kann ich mir nicht so richtig erklären.

    Aber dafür der Handbuchabschnitt zu mysqli_query ...
    Du solltest ihn lesen - und verstehen.

    Freundliche Grüße

    Vinzenz

    1. Hallo

      übrigens unterlaufen Dir außer dem Escaping und der Missachtung von Rückgabewerten noch etliche weitere Fehler:

      function checkUserData($name, $password){

      Die Übergabeparameter sind $name und $password.

      $q = "SELECT
                  password
                FROM
                  member
                WHERE
                  name = '".$username."'";

      Tja, eine Kontrollausgabe von $q hätte Dich darauf hinweisen können, dass Du etwas falsch gemacht hast.

      Eine Benutzereingabe von O'Brien (ein Nickname hier im Forum) hätte ebenfalls eine Fehlermeldung zur Folge, ich könnte mir noch lustigere Eingaben mit noch interessanteren Konsequenzen vorstellen ...

      Aber weiter im Text:

      Woher kommt die Variable $username? Verläßt Du Dich etwa auf register_globals?

      Warum überprüfst Du nicht gleich auch noch das Passwort mit?
      Warum übergibst Du überhaupt $password?
      Was sollte diese Funktion überhaupt bewirken?
      Jedenfalls keinen User authentifizieren, sie sähe ja nur nach, ob es den Benutzer auch gibt, genauer sie schaut nach, wie oft es einen Benutzer gibt.

      Traurig, traurig, traurig ...

      function login(){
          $this->checkUserData("Hans");

      sollte eine Notice ergeben. $password hat keinen Defaultwert und wird nicht übergeben.

      }

      Traurig, traurig, traurig ...

      Noch ein Hinweis:
      Es ist eine ausgezeichnete Idee, Code ordentlich zu kommentieren. Ich vermisse jeglichen Kommentar. Selbst Dir müsste doch auffallen, dass die Methode

      check_user_data

      ihren Namen völlig zu Unrecht trägt.

      Es könnte so einfach sein:
      Lege zuerst die Schnittstelle Deiner Funktion/Methode fest
      (nutze Kommentare)

      - Eingabe
       - Ausgabe

      Implementiere anschließend die Methode.

      Freundliche Grüße

      Vinzenz

    2. Hallo!

      Solcher Code gehört verboten! Du liest doch hier recht viel mit.

      Mitlesen schützt nicht vor Anfängerfehlern. Vorallem dann nicht, wenn man ein Anfänger ist.

      Warum arbeitest Du nicht mit mysqli_prepare, bind_param(),  und mysqli_stmt_execute()

      Weil mir diese Funktionen neu sind. Leider kenne ich noch nicht alle Funktionen von PHP. Aber ich bemühe mich, das zu erreichen.

      ...oder wenigstens mit mysqli_real_escape_string.

      Weil es nur ein minimaler Ausschnitt meines Codes ist. Und ich weiß, wie *meine* Eingabe aussieht. Meinen Code mit mysqli_real_escape_string unübersichtlicher machen, kann ich dann, wenn erst mal die Grundfunktionen laufen. Aber da der Code nur auf meinem bescheidenen Apachen laufen soll, habe ich jetzt alle Sicherheitsaspekte ausser acht gelassen.

      Warum verwendest Du nicht den objektorientierten Ansatz, wenn Du schon versuchst, objektorientiert zu programmieren?

      Muss ich das, damit mein Beispiel funktioniert? AFAIK nicht. Ich habe auch erst vor etwas mehr als einer Stunde gesehen, dass man dies auch objektorientiert programmieren kann.

      Du übersiehst also die Möglichkeit, dass Deine Abfrage fehlschlägt. Du übersiehst die Möglichkeit, dass in $result _nicht_ vom Typ mysqli_result ist.

      Ok, danke. Da war mein Denkfehler. Bin auf der Leitung gestanden.

      Also ich entschuldige mich dafür, dass ich Anfängerfehler mache. Das liegt aber warscheinlich daran, dass ich einer bin. Wenn du von Anfang an wunderbar sicheren und objektorientierten Code schreiben konntest, dann beneide ich dich darum. Da es aber warscheinlich 2 bis 3 Leute gibt, die dieses Glück nicht haben, bitte ich dich, einfach ein bisschen Verständnis zu haben. Nochmals danke für die Hilfe.

      ciao, ww

      --
      Ein japanisch-deutsches Gedicht
      sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
      1. Hi,

        Mitlesen schützt nicht vor Anfängerfehlern. Vorallem dann nicht, wenn man ein Anfänger ist.

        => http://community.de.selfhtml.org/my/zitatesammlung/abstimmen

        Warum verwendest Du nicht den objektorientierten Ansatz, wenn Du schon versuchst, objektorientiert zu programmieren?
        Muss ich das, damit mein Beispiel funktioniert? AFAIK nicht. [...]
        Also ich entschuldige mich dafür, dass ich Anfängerfehler mache. Das liegt aber warscheinlich daran, dass ich einer bin. Wenn du von Anfang an wunderbar sicheren und objektorientierten Code schreiben konntest, dann beneide ich dich darum. Da es aber warscheinlich 2 bis 3 Leute gibt, die dieses Glück nicht haben, bitte ich dich, einfach ein bisschen Verständnis zu haben. Nochmals danke für die Hilfe.

        Nun mal ruhig mit den jungen Pferden. Du bist eigentlich lange genug hier, um zu wissen, was derlei Fragen bedeuten: Es sind diejenigen Fragen, die Du Dir selbst stellen würdest, wenn Du über entsprechendes Wissen und Erfahrung verfügen würdest; und damit diejenigen Fragen, über die Du nachdenken solltest, um besagtes Wissen und Erfahrung zu erlangen. Du weißt, was eine rhetorische Frage ist?[1]

        Also, bitte wittere nicht gleich einen Affrond. Das macht sich nicht gut in Deinem Führungszeugnis ;-)

        Cheatah

        [1] Anwesende natürlich ausgeschlossen, äh ...

        --
        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
        1. Hallo!

          Mitlesen schützt nicht vor Anfängerfehlern. Vorallem dann nicht, wenn man ein Anfänger ist.

          => http://community.de.selfhtml.org/my/zitatesammlung/abstimmen

          :-)

          Nun mal ruhig mit den jungen Pferden. Du bist eigentlich lange genug hier, um zu wissen, was derlei Fragen bedeuten: Es sind diejenigen Fragen, die Du Dir selbst stellen würdest, wenn Du über entsprechendes Wissen und Erfahrung verfügen würdest; und damit diejenigen Fragen, über die Du nachdenken solltest, um besagtes Wissen und Erfahrung zu erlangen.

          Naja, das hätte ich warscheinlich so auffassen sollen. Aber ohne einen Affront heraufbeschwören zu wollen, muss ich sagen, dass die Antwort von Vinzenz Mai äußerst arrogant rüberkam. Ob das so gewollt war kann ich nicht beurteilen. Aber sein andauerndes traurig³ ist nicht die beste Art und Weise um jemandem zu sagen "hey, schau mal: da hast du einen Fehler und mit der Funktion xy() geht's noch besser".

          Das macht sich nicht gut in Deinem Führungszeugnis ;-)

          Hab ich eines? Cool. Wo kann ich das mir mal anschauen? :-)

          ciao, ww

          --
          Ein japanisch-deutsches Gedicht
          sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
          1. hallo wichtel,

            Aber ohne einen Affront heraufbeschwören zu wollen, muss ich sagen, dass die Antwort von Vinzenz Mai äußerst arrogant rüberkam. Ob das so gewollt war kann ich nicht beurteilen.

            War es mit Sicherheit nicht. Vinzenz ist einer der geduldigsten und nachsichtigsten Helfer hier im Forum und verfügt über mehr als genügend Sachkompetenz, um ernstgenommen werden zu können.

            Das macht sich nicht gut in Deinem Führungszeugnis ;-)
            Hab ich eines? Cool. Wo kann ich das mir mal anschauen? :-)

            Psssst - ich verrate dir mal ein Geheimnis: auf solche Informationen haben nur Mitglieder des inner circle wirklich Zugriff.

            Grüße aus Berlin

            Christoph S.

            --
            Visitenkarte
            ss:| zu:) ls:& fo:) va:) sh:| rl:|
            1. Hallo!

              Mitglieder des inner circle

              Sind das die Tempelritter von SELFHTML?

              ;-)

              ciao, ww

              --
              Ein japanisch-deutsches Gedicht
              sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
      2. Hallo,

        es tut mir leid, dass meine Postings auf Dich äußerst arrogant wirkten.
        Das war das genaue Gegenteil dessen, was ich beabsichtigte. Es ist ein
        wirkungsvolles Beispiel für die Macht des ersten Eindruckes. Dieser war
        bei Dir extrem negativ, deswegen habe ich den Eindruck, dass Dir in der
        Folge die Bereitschaft fehlte, Dich konstruktiv mit meinen Anmerkungen
        auseinanderzusetzen.

        Nun mal ruhig mit den jungen Pferden. Du bist eigentlich lange genug hier, um zu wissen, was derlei Fragen bedeuten: Es sind diejenigen Fragen, die Du Dir selbst stellen würdest, wenn Du über entsprechendes Wissen und Erfahrung verfügen würdest; und damit diejenigen Fragen, über die Du nachdenken solltest, um besagtes Wissen und Erfahrung zu erlangen.
        Naja, das hätte ich warscheinlich so auffassen sollen. Aber ohne einen Affront heraufbeschwören zu wollen, muss ich sagen, dass die Antwort von Vinzenz Mai äußerst arrogant rüberkam. Ob das so gewollt war kann ich nicht beurteilen. Aber sein andauerndes traurig³ ist nicht die beste Art und Weise um jemandem zu sagen "hey, schau mal: da hast du einen Fehler und mit der Funktion xy() geht's noch besser".

        Statt "arrogant" sollten die Postings einen Anflug von Komik, von Humor
        vermitteln, schließlich war Theo Lingen ein begnadeter Komiker - und die
        "Glanzlichter des deutschen Spielfilms", aus denen mein Zitat

        "Traurig, traurig, traurig ..."

        stammt, sind längst längst vergessen. Nur die Erinnerung an Theo Lingen
        hat überlebt.

        Damit sind wir wieder beim Thema. Ich hatte meine Inhalte nicht korrekt
        gemäß des Kontextes maskiert. D.h. ich hätte davon ausgehen müssen, dass
        Du, da ein paar Jahrzehnte jünger, mit diesem Zitat nichts anfangen kannst

        • und hätte überlegen sollen, wie es auf jemanden wirken könnte, der es
          nicht kennt.

        Damit kommen wir zu

        ...oder wenigstens mit mysqli_real_escape_string.
        Weil es nur ein minimaler Ausschnitt meines Codes ist. Und ich weiß, wie *meine* Eingabe aussieht. Meinen Code mit mysqli_real_escape_string unübersichtlicher machen, kann ich dann, wenn erst mal die Grundfunktionen laufen. Aber da der Code nur auf meinem bescheidenen Apachen laufen soll, habe ich jetzt alle Sicherheitsaspekte ausser acht gelassen.

        Nein. Dieser Ansatz ist leider falsch. Er ist schlimmer als arrogant, er
        ist ignorant. Es ist eine gute Idee, möglichst früh damit anzufangen,
        sauberen und sicheren Code zu schreiben.

        Also ich entschuldige mich dafür, dass ich Anfängerfehler mache. Das liegt aber warscheinlich daran, dass ich einer bin.

        Ich erwarte keine Entschuldigung für Fehler in Quellcode. Es ist viel
        besser, aus Hinweisen auf solche Fehler entsprechende Konsequenzen zu
        ziehen - und diese in Zukunft vermeiden zu wollen.

        Wenn du von Anfang an wunderbar sicheren und objektorientierten Code schreiben konntest, dann beneide ich dich darum. Da es aber warscheinlich 2 bis 3 Leute gibt, die dieses Glück nicht haben, bitte ich dich, einfach ein bisschen Verständnis zu haben. Nochmals danke für die Hilfe.

        Selbstverständlich habe ich selbst auch schon genug mangelhaften Code erstellt,
        siehe z.B. auch </archiv/2006/5/t128804/#m832538>. Das hindert mich nicht daran,
        Hinweise zu geben, wie man es nach heutigem Stand besser machen kann.

        Es ist ein ganz wichtiger Grundsatz, dass Daten entsprechend dem Kontext, in
        dem sie gerade verwendet werden, maskiert werden. Im Falle des Speicherns in
        eine MySQL-Datenbank wären das z.B. die traditionellen Funktionen
        mysql_real_escape_string bzw. mysqli_real_escape_string. Mehr zum Maskieren
        in Abhängigkeit vom Kontext steht in Postings von (vor allem) Sven Rautenberg
        und dedlfix. Nutze dazu die Forumssuche, eingeschränkt auf die Jahre 2006 und
        2007.

        Warum arbeitest Du nicht mit mysqli_prepare, bind_param(),  und mysqli_stmt_execute()

        Weil mir diese Funktionen neu sind. Leider kenne ich noch nicht alle Funktionen von PHP. Aber ich bemühe mich, das zu erreichen.

        Diesen Ehrgeiz hatte ich nie :-) Es ist allerdings immer eine gute Idee, im
        Handbuch zu stöbern und nachzuschauen, welche Möglichkeiten es in einem
        Bereich noch gibt, mit dem man sich gerade befasst.

        Die Vorgehensweise mit "prepared Statements" ist insbesondere im MySQL-Umfeld
        noch recht unbekannt. Die bereits vorhandene Literatur, insbesondere auch die
        Tutorials verweilen zum Teil noch auf recht altem Stand. Gerade bei den beiden
        sich schnell entwickelnden Systemen PHP und MySQL kann man das einerseits gut
        nachvollziehen. Andererseits ist die Menge an vorhandenen Texten, auch Büchern,
        mit ihrem oftmals miserablen Code daran schuld, dass viele Neulinge genau nach
        diesen Mustern vorgehen, danach lernen.

        Du hast jedoch einen großen Vorteil. Du hast dieses Forum hier entdeckt, das
        Dich sehr oft auf Fehler hinweist, auf bessere Möglichkeiten hinweist, auch
        wenn Dein eigener Code der eigenen Angabe zufolge doch "funktioniert". Wie
        Chraecker Heller es so schön ausdrückte:

        "Uns gibt es nur mit Meinung und ungebetener Beratung."
        http://community.de.selfhtml.org/zitatesammlung/zitat224

        Freundliche Grüße

        Vinzenz

        1. Hallo!

          Dieser war bei Dir extrem negativ, deswegen habe ich den Eindruck, dass Dir in der
          Folge die Bereitschaft fehlte, Dich konstruktiv mit meinen Anmerkungen
          auseinanderzusetzen.

          Gestern Nacht war die Bereitschaft wirklich auf dem Nullpunkt. Aber ich arbeite mich gerade fleißig durch die einzelnen Postings bzw. Abschnitte im Handbuch :)

          Statt "arrogant" sollten die Postings einen Anflug von Komik, von Humor
          vermitteln, [...]

          Achso. Gut dass ich das jetzt weiß. Dann bin ich jetzt ja vorbereitet :)

          Nein. Dieser Ansatz ist leider falsch. Er ist schlimmer als arrogant, er
          ist ignorant. Es ist eine gute Idee, möglichst früh damit anzufangen,
          sauberen und sicheren Code zu schreiben.

          Mein Ansatz war: Zuerst schreibe ich den Code. Wenn es Fehler gibt, dann baue ich den Code wieder auseinander, um die Fehlerquelle zu finden. Das habe ich dann auch gemacht. Und sobald mein Code funktioniert wollte ich die Eingaben überprüfen und maskieren. Aber dann versuche ich es eben, schon ganz von Anfang an umzusetzen.

          Es ist viel besser, aus Hinweisen auf solche Fehler entsprechende »» Konsequenzen zu ziehen - und diese in Zukunft vermeiden zu wollen.

          Auf jeden Fall will ich das.

          Nutze dazu die Forumssuche, eingeschränkt auf die Jahre 2006 und
          2007.

          Mache ich.

          Diesen Ehrgeiz hatte ich nie :-) Es ist allerdings immer eine gute Idee, im
          Handbuch zu stöbern und nachzuschauen, welche Möglichkeiten es in einem
          Bereich noch gibt, mit dem man sich gerade befasst.

          Ich habe diesen Ehrgeiz schon. Allerdings bin ich mir nicht sicher ob ich mein Ziel erreichen werde :)

          ciao, ww

          --
          Ein japanisch-deutsches Gedicht
          sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
  2. Ich habe ein Problem mit folgendem Code:

    $result = mysqli_query($this->connection, $q);
        $row_cnt = mysqli_num_rows($result); # Das hier ist "Line 20"

    Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in D:\xampp\xampp\htdocs\test2.php on line 20

    Das kann ich mir nicht so richtig erklären.

    Wie üblich: Es wird einfach davon ausgegangen, dass Fehler auf diesem Planeten nicht existieren und Hinweise wie "Rückgabewerte: Gibt bei Erfolg TRUE zurück, im Fehlerfall FALSE." nur zur Belustigung des Publikums in der Anleitung stehen.