+ (PHP): mysqli_num_rows() erwartet Parameter?
wucher wichtel
- datenbank
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
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
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
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
Grundlage für Zitat #682.
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 ...
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
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.
Hallo!
Mitglieder des inner circle
Sind das die Tempelritter von SELFHTML?
;-)
ciao, ww
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
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
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
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.