Fehler in mysqli code und call_user_func_array ()

8

Ich bekomme einige Fehler, wenn ich versuche, eine dynamische where-Klausel mit mysqli:

zu erstellen
  

Warnung: Parameter 2 für mysqli_stmt :: bind_param () sollte a sein   Referenz, Wert angegeben in ... in Zeile 319

     

Warnung: mysqli_stmt :: execute (): (HY000 / 2031): Keine Daten für geliefert   Parameter in vorbereiteter Anweisung in ... in Zeile 328

     

Warnung: mysqli_stmt :: bind_result (): (HY000 / 2031): Keine Daten bereitgestellt   für Parameter in vorbereiteter Anweisung in ... in Zeile 331

     

Warnung: mysqli_stmt :: store_result (): (HY000 / 2014): Befehle aus   synchronisieren; Sie können diesen Befehl jetzt nicht in ... in Zeile 332

ausführen

Ich rate, es gibt eine kleine Änderung, die benötigt wird, um die Probleme zu lösen, aber was passiert, wenn eines der beiden Drop-down-Menüs nicht gleich All ist oder wenn beide nicht gleich All sind, dann wird es angezeigt mit den Fehlern.

Unten sehen Sie den Code, der sowohl die Dropdown-Menüs als auch die Abfrage (mit dynamischer where-Klausel) anzeigt, die abhängig von den gewählten Optionen folgt:

HTML:

Studenten Dropdown-Menü:

%Vor%

Frage Nummer Dropdown-Menü

%Vor%

PHP / MySQL:

%Vor%

Hier ist eine DEMO: DEMO

Wählen Sie in der Demo eine Bewertung aus dem Dropdown-Menü und senden Sie sie. Sie werden die zwei Dropdown-Menüs sehen. Halte sie beide als All und submit, es wird die Abfrage ohne Probleme ausgeben. Nein, ändern Sie All in einem der Drop-down-Menüs in einen bestimmten Schüler oder eine bestimmte Frage und reichen Sie sie ein. Jetzt sehen Sie die Fehler

VAR DUMP:

Das Ergebnis von var_dump(array_merge(array($parameterTypes), $parameters))); , wenn ich Sitzung (Assessment) mit Wert 31 , Schülernummer Wert 40 und Frage Nummer Wert 81 und WHERE CLAUSE WHERE q.SessionId = ? AND sa.StudentId = ? AND q.QuestionId = ? :

wähle

Ich bekomme diese Ausgabe: array(4) { [0]=> string(3) "iii" [1]=> string(2) "31" [2]=> string(2) "40" [3]=> string(2) "81" }

    
user1914374 27.01.2013, 05:15
quelle

3 Antworten

2

Dies ist eine klebrige Situation, die durch die Änderung von call_user_func_array Verhalten in PHP 5.4 verursacht wird (ich muss annehmen): Dokumentation

So hässlich das ist, wird es funktionieren, bind_param auf diese Weise aufzurufen:

%Vor%

Ich hasse das so sehr, wie Sie wahrscheinlich tun. Ich schlage vor, von mysqli zu PDO zu wechseln, das variable Parameter viel besser verarbeitet (und meiner Meinung nach eine bessere Syntax hat):

%Vor%     
Explosion Pills 31.01.2013, 00:31
quelle
0
  

Warnung: Parameter 2 für mysqli_stmt :: bind_param () sollte eine Referenz sein, Wert in ... in Zeile 319

Dies sollte selbsterklärend sein: Die Argumente von bind_param werden als Referenz übergeben und müssen daher Variablen sein. Was Sie vielleicht übersehen haben, ist, dass array_merge ein neues Array zurückgibt, das keine Verweise auf die ursprünglichen Variablen enthält, sondern nur Werte.

Die folgenden Fehler sind unmittelbar danach, weil die Parameter nicht gebunden waren.

Eine mögliche Lösung ist, Referenzen in Ihrem $parameters -Array zu speichern, diese werden sogar von array_merge beibehalten:

%Vor%

Nun sind die Array-Elemente von $parameters Verweise auf POST-Variablen und die Array-Elemente von array_merge ebenfalls.

Bearbeiten: sieht so aus, als ob das nicht mehr möglich ist, siehe @Explosionspillen

    
Fabian Schmengler 31.01.2013 00:16
quelle
0

Das ist immer noch nicht genug, um mysqli für PDO abzulehnen, besonders wenn ich damals sehr gute Gründe hatte, PDO nicht zu benutzen. Auf der anderen Seite, ja, sie mussten die Methoden mysqli_stmt :: bind_param und bind_result nicht erzwingen, um zu verlangen, dass die Variablen vonRef übergeben wurden, sie konnten sie ein Array zurückgeben lassen. Das eigentliche Problem hierbei ist, dass Call-Time-Pass-by-Reference nicht mehr möglich ist, aber mysqli immer noch Pass-by-Reference benötigt, so dass jeder, der dynamische Parameter verwendet (jemand mit intuitivem SQL), gefangen wird in dieser Ausgabe, mich eingeschlossen. Nachdem ich Stunden damit verbracht habe, eine benutzerdefinierte mysqli-Wrapper-Klasse zu schreiben, die Array-Sets in dynamisch vorbereitete SQL-Anweisungen konvertiert, werde ich nicht versuchen, alles neu zu schreiben, um mit PDO zu arbeiten, besonders da PDO die Parameter als Teil der Bindung benennen muss. Ich müsste mehrere Funktionen schreiben, um die Liste dessen, was gesendet wurde, für jeden Abfragetyp zu erstellen. Das ist kontraintuitiv, und ich werde nicht unzählige Stunden damit verschwenden, das nachzuahmen, was ich mit mysqli erreicht habe.

Die einzige Schwierigkeit an diesem Punkt ist, dass wir die Variablen in call_user_func_array () byRef nicht übergeben können und dass mysqli_stmt :: bind_ * verlangt, dass sie vonRef ... übergeben werden. Die einzigen Optionen sind 1) schreibe ein neues call_user_func_array () - Funktion, die explizit für die Methoden bind_ * entworfen wurde, wobei die übergebenen Parameter im Wesentlichen in ein neues Array oder eine Gruppe von Variablen mit args kopiert werden und dann byRef beim Callback übergeben werden; oder 2) schreibe die mysqli-Klasse neu, um es richtig zu machen, und schaue einfach, was passiert ist, führe die SQL aus und gebe das Ergebnis wie vorgesehen zurück. Es gibt keinen Grund, dass das, was wir an eine Methode übergeben, um SQL auszuführen, mit Ergebnissen durcheinander gebracht werden muss, es sollte genauso behandelt werden wie eine SQL-Konsole.

Da ich vom Codieren viel zu erschöpft bin, bis meine Augen fast bluten, werde ich die nicht vorgeschlagene Option nehmen, meine PHP-Version bei 5.3.10-1 festzuhalten, bis ich das Problem tatsächlich richtig gelöst habe. Für diejenigen, die argumentieren "für all diese Bemühungen, warum nicht einfach nur für das Schreiben Ihres PDO-Wrappers?" ... und meine Antwort ist einfach: Ich benutze PHP und MySQL ausschließlich für viele Projekte, bei denen der Server ein winziger kleiner Computer ist mit sehr begrenztem Raum und Ressourcen, ganz zu schweigen von der CPU-Fähigkeit. PDO lädt ALLES, was es tun kann, nicht nur das, was Sie verwenden werden, daher gibt es in Ihren Ressourcen einige Vorbehalte für Dinge, die Sie nicht einmal nutzen werden, die meine Projekte nicht verlieren können.

Zum Glück wird es nicht schädlich sein, meine PHP-Version zurückzuhalten. Das ist es, was viele Serverfarmen auf Unternehmensebene tun, um zu vermeiden, dass alles heruntergefahren werden muss, um "auf der aktuellen Version" von etwas zu sein, was auch unglaublich teuer ist, alle paar Jahre zu aktualisieren.

    
user253780 23.04.2016 08:41
quelle

Tags und Links