Prepared Statements - Wie verwenden?

Anmerkungen, Fragen und Hinweise zur Konfiguration dürfen in diesem Forum gepostet werden. // Notes, questions, and hints on the configuration can be posted here.
Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: Prepared Statements - Wie verwenden?

Beitrag von ma2604121 » 29.03.2011, 23:32:31

Screeze hat geschrieben:(...) sollte der Fehler nichtmehr auftreten, denke ich.
So funktioniert zumindest vorläufig alles. Es erscheint keine Fehlermeldung und die Daten werden eingetragen.

Vielen Dank für die Mühe!

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 09:48:54

Christian wird sich der Sache bestimmt auch nochmal annehmen und darüber schauen :)

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: Prepared Statements - Wie verwenden?

Beitrag von dr.e. » 30.03.2011, 10:42:57

Hallo dave & Ralf,

vorneweg: die mysqli-Extension reagiert an einigen Stellen mehr als abenteuerlich, insofern habe ich mit Spannung die Threads gelesen. Danke also für eure Zusammenarbeit um diesen Krempel wenigstens über das APF mit einer vernünftigen API zu versehen! :)

@all
Was den Bug/das Verhalten angeht, so liegt die Ursache darin, dass bei einem INSERT keine Meta-Daten vorhanden sind, die Methoden executeTextBindStatement() und executeBindStatement() beim Aufruf der Methode fetchBindResult() aber davon ausgegangen sind. Scheinbar ist das bei meinen Tests während der Entwicklung aber anders gewesen oder an der Extension hat sich etwas verändert.

Ich habe zur Anpassung an diesen Fall folgende Anpassung in fetchBindResult() vorgenommen:

Code: Alles auswählen

   private function fetchBindResult(&$query) {
      $metaData = $query->result_metadata();

      // in case the meta data is not present (e.g. for INSERT statements),
      // we cannot fetch any data. thus we return null to indicate no result
      if($metaData === false){
         return null;
      } 
Zusätzlich dazu hat die Methode bindParams() noch eine frische Signatur um die Übergabe-Parameter hinsichtlich des Datentyps zu validieren:

Code: Alles auswählen

private function bindParams(&$query, array $params) 
selbiges habe ich auch für executeTextBindStatement(), executeBindStatement() und executeStatement() umgesetzt. Die Änderungen beziehen sich allerdings auf 1.14.

Für 1.13 kannst du die obigen Anpassungen in den Code patchen.
Viele Grüße,
Christian

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: Prepared Statements - Wie verwenden?

Beitrag von ma2604121 » 30.03.2011, 11:40:24

Nochmals vielen Dank für die schnelle Hilfe! Definitiv ein Pluspunkt des APF!

Jetzt habe ich aber immer noch eine Frage hinsichtlich der Verwendung von MySQLi:
Wenn ich z.B. die MySQLi-Eigenschaft insert_id verwenden will - wie stelle ich das an? Oder geht das gar nicht?

Kann ich alle Eigenschaften und Methoden von MySQLi verwenden?

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 11:59:48

ma2604121 hat geschrieben:Nochmals vielen Dank für die schnelle Hilfe! Definitiv ein Pluspunkt des APF!
Deswegen habe ich mich auch zur Entwicklung mit dem APF entschlossen! ;)
ma2604121 hat geschrieben: Jetzt habe ich aber immer noch eine Frage hinsichtlich der Verwendung von MySQLi:
Wenn ich z.B. die MySQLi-Eigenschaft insert_id verwenden will - wie stelle ich das an? Oder geht das gar nicht?
Wenn du beispielsweise eine Abfrage folgendermassen durchführst:

Code: Alles auswählen

$data = $SQL->executeTextBindStatement('INSERT INTO user (nick, pwd) VALUES (?, ?)', array($nick, $password));
 
sollte in der $data-Variable die last_id bereits enthalten sein.

Dies findet man auch wieder in der MySQLiHandler.php Zeilen 306 f:

Code: Alles auswählen

// track $__lastInsertID fur further usage
$this->__lastInsertID = $query->insert_id;
 
Allerdings deute ich das mal so, an anderer Stelle ist es auch so :)
ma2604121 hat geschrieben:Kann ich alle Eigenschaften und Methoden von MySQLi verwenden?
Du kannst die MySQLiHandler.php ja mal nach den Eigensachaften und Methoden durschsuchen. Dann weisst du genau, welche Methoden es gibt und welche nicht ;). Vllt. hilft dir die API da auch weiter:
http://files.adventure-php-framework.or ... ndler.html

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: Prepared Statements - Wie verwenden?

Beitrag von ma2604121 » 30.03.2011, 12:15:07

dave hat geschrieben:Wenn du beispielsweise eine Abfrage folgendermassen durchführst:

Code: Alles auswählen

$data = $SQL->executeTextBindStatement('INSERT INTO user (nick, pwd) VALUES (?, ?)', array($nick, $password));
 
sollte in der $data-Variable die last_id bereits enthalten sein.

Dies findet man auch wieder in der MySQLiHandler.php Zeilen 306 f:

Code: Alles auswählen

// track $__lastInsertID fur further usage
$this->__lastInsertID = $query->insert_id;
 
Sollte wohl so sein. Aber ein

Code: Alles auswählen

var_dump($data) 
ergibt ein

Code: Alles auswählen

bool(false)  
wie bereits weiter oben festgestellt wurde. Die Daten wurden eingefügt - also sollte eigentlich eine ID bekannt sein.

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 12:28:09

ma2604121 hat geschrieben:Sollte wohl so sein. Aber ein

Code: Alles auswählen

var_dump($data) 
ergibt ein

Code: Alles auswählen

bool(false)  
wie bereits weiter oben festgestellt wurde. Die Daten wurden eingefügt - also sollte eigentlich eine ID bekannt sein.
Ja, richtig, das haben wir doch gestern raus genommen ... Durch Alkohol zum Abend bin ich immer vergesslich

Da müssten wir das ganze noch etwas weiter anpassen. Die letzte ID ist definitiv durch zuvor geposteten Codfe-Schnipsel bekannt, wir müssen diese nun nur wieder zurück geben.

Das machen wir am besten in unserer Erweiterung, die wir gestern in die Methode bindParams() eingebaut haben. Du könntest mal folgendes versuchen:

Unsere if-Abfrage in der bindParams-Function so abändern:
Aus

Code: Alles auswählen

      if($metaData === false){
         return null;
      }
 
machen wir

Code: Alles auswählen

      if($metaData === false){
         return $this->__lastInsertID;
      }
 
Somit hast du durch den var_dump[$data] die ID, wenn alles korrekt ist ^^. Allerdings weiss ich ich gerade nicht, ob die Funktion dann weiter durchlaufen wird und somit wieder den fatal Error wirft. Mir fehlen da einfach noch ein paar Grundkenntnisse bei PHP ^^ Aber ich glaube, das müsste klappen.

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: Prepared Statements - Wie verwenden?

Beitrag von ma2604121 » 30.03.2011, 12:37:34

Das klappt.

Allerdings dürfte das ebenfalls nicht die "optimale" Lösung sein, da executeTextBindStatement nicht nur die insert_id (Z. 307), sondern auch num_rows (Z. 318) liefern sollte.

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 12:44:25

Da bleibt dir erstmal nichts anderes übrig, als entweder:
- damit zu leben
- oder selbst Hand anzulegen und das zu optimieren
- oder wir versuchen gemeinsam die notwendigen Dinge zu implementieren. Nur kann ich da eben rein gar nichts testen ;)

Aber das num_rows mit zurück zu liefern sollte kein Problem sein. Das kannst du ganz einfach noch mit in den return einbauen.

Christian ist ja selbst, wenn ich seinen Post richtig deute, nicht sehr begeistert von MySQLi ;).

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: Prepared Statements - Wie verwenden?

Beitrag von ma2604121 » 30.03.2011, 12:51:33

dave hat geschrieben:Da bleibt dir erstmal nichts anderes übrig, als entweder:
- damit zu leben
Die schlechteste Lösung...
dave hat geschrieben:- oder wir versuchen gemeinsam die notwendigen Dinge zu implementieren. Nur kann ich da eben rein gar nichts testen ;)
Zum Testen habe ich momentan genug Zeit.
dave hat geschrieben:Aber das num_rows mit zurück zu liefern sollte kein Problem sein. Das kannst du ganz einfach noch mit in den return einbauen.
Das müsste dann vermutlich als Array zurückgeliefert werden?
dave hat geschrieben:Christian ist ja selbst, wenn ich seinen Post richtig deute, nicht sehr begeistert von MySQLi ;).
In die Richtung kann man es deuten. ;)
Wobei ich bisher ganz zufrieden mit MySQLi war und bin.

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 13:00:13

ma2604121 hat geschrieben:Zum Testen habe ich momentan genug Zeit.
Ja, dann können wir uns dem ja nach und nach annehmen. Kann aber keine Garantie geben, bin auch noch ziemlicher Anfänger ;).
ma2604121 hat geschrieben:Das müsste dann vermutlich als Array zurückgeliefert werden?
Wäre erstmal die einfachste Möglichkeit.

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: Prepared Statements - Wie verwenden?

Beitrag von ma2604121 » 30.03.2011, 13:26:12

Da ist eben die Frage wie das APF insgesamt seine Arrays (strukturell) aufbaut. Mit den "Innereien" habe ich mich bislang wenig bis gar nicht beschäftigt.

Zudem ist die Frage, ob es sinnvoll ist, hier eigene Wege zu gehen und nun eine Lösung zu "schustern", nur damit ich mit meinem Projekt voran komme. Es hilft schließlich nichts, wenn ich beim nächsten APF-Update alle Änderungen erneut vornehmen muss.

Vielleicht sollte ich einfach auf das normale MySQL umsteigen? Wäre allerdings hinsichtlich der möglichen Fehler in der MySQLi-Umsetzung des APF auch keine saubere Lösung.

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 13:41:18

Wenn wir eine insgesamt saubere Lösung hinbekommen, wird das in die aktuelle 1.14 eingechceckt und somit geht auch nichts verloren. Mein Problem ist dabei einfach nur diese SVN-Geschichte ... komm damit gar nicht klar ;)

Ich finde es ja gut, dass es jemanden gibt, der MySQLi nutzt, erst dadurch werden ja die noch vorhandenen Probleme erkannt.

Ich frage jetzt einfach mal, wo es bei dir noch überall hakt. Dann überdenken wir das nochmal, probieren das Stück für Stück hier aus und nehmen das dann in die neue APF-Version mit auf. Und wenn es auch mit dem 1.14 später noch Ploblemchen geben sollte, kommts in die Version 1.15 usw. ... Stück für Stück eben ...

Christian ist da ja glücklicherweise sehr flexibel! ;)

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: Prepared Statements - Wie verwenden?

Beitrag von ma2604121 » 30.03.2011, 13:46:17

dave hat geschrieben:Ich finde es ja gut, dass es jemanden gibt, der MySQLi nutzt, erst dadurch werden ja die noch vorhandenen Probleme erkannt.
Das ist wohl wahr.
dave hat geschrieben:Ich frage jetzt einfach mal, wo es bei dir noch überall hakt.
Was genau meinst Du damit?

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: Prepared Statements - Wie verwenden?

Beitrag von dave » 30.03.2011, 13:48:48

ma2604121 hat geschrieben:Was genau meinst Du damit?
Wo hast du noch bei dir Probleme bei der Datenbankanbindung via MySQLi? Was funktioniert nicht, wo gibt es noch Verbesserungsbedarf seitens des APF?

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast