ChrisB: Fehlermeldung bei UPDATE von Datensatz

Beitrag lesen

Hi,

Mein Problem ist zwar gelöst, aber ich würd trotzdem noch gerne die var_dump Ausgabe besser verstehen:

object(mysqli_stmt)#2 (0) { } sagt mir mal, daß $kommando ein Objekt mit der Methode "mysqli_stmt" ist, hab ich das richtig verstanden?

Nein, es ist ein Objekt vom Typ MySQLi_STMT. Genau so eins soll die Methode prepare des MySQLi-Objektes im Erfolgsfalle ja zurueckliefern - was hiermit jetzt auch kontrolliert waere.

Und was sagt das "#2 (0) { }" aus?

Die #0 duerfte vermutlich eine Ressourcen-Kennung sein, und { } besagt, dass das Objekt weiter keinen Inhalt hat, der sich an dieser Stelle sinnvoll in Textform repraesentieren liesse - dass muss uns jetzt in diesem Falle aber beides nicht weiter interessieren, denn was wir wissen wollten/mussten, wissen wir ja jetzt - wir haben erfolgreich ein Objekt vom Typ MySQLi_STMT erzeugt, und koennen damit anschliessend weiter arbeiten.

Das war jetzt erst mal die detailierte Fehlersuche.
Normalerweise wirst du aber auf deiner Webseite keine Kontrollausgabe in der Form, wie var_dump sie hier geliefert hat, dem Benutzer zeigen wollen.

Also fragt man da normalerweise nur ab, ob die prepare-Methode false zurueckgeliefert hat, oder nicht - denn das ist laut Handbuch ihr definiertes Verhalten, sie liefert entweder ein Objekt vom Typ MySQLi_STMT im Erfolgsfall, oder false bei einem Fehler.

Also schreibt man sowas normalerweise eher in der Form:

if(!($kommando = $db->prepare($aendern)) { // wenn der Rueckgabewert false ist  
  // hier eine Fehlermeldung fuer den Benutzer ausgeben,  
  // weitere Verarbeitung abbrechen  
}  
$kommando->bind_param(...); // hier mit erfolgreich erstelltem MySQLi_STMT weiterarbeiten

Ich habe gerade mehrmals deine Erklärung zu meiner Frage "Was heißt denn "Ein Objekt, das eine Methode ... besitzt"?" gelesen. Das ist aber schon _sehr_ verwirrend, hm? :-)

Ich weiss nicht, ob ich es "gut" erklaert habe.
Das ist halt ein umfangreiches Thema, und demzufolge schwer in zwei Saetzen abzuhandeln. Aber ich wollte an der Stelle nicht weiter ausholen, als noetig - denn auf dich stroemt ja gerade sowieso genug an neuen Informationen ein. (Du koenntest uebrigens MySQLi auch nicht objektorientiert, sondern auf prezedurale Weise nutzen - ohne Objekte zu erzeugen, nur mit Funktionen; das aber nur der Vollstaendigkeit halber, jetzt bleibe lieber mal bei dem bestehenden Code, den du hast, sonst wird das noch verwirrender.)

Dann hast du dabei bisher lediglich *Glueck* gehabt, wenn du dabei auf jegliche Erfolgskontrolle bei Objekterzeugungen und Methodenaufrufen ebenso verzichtet hast.

Wie meintest Du das? Nehmen wir als Beispiel das Anlegen eines neuen Datensatzes. Das habe ich so gelöst:

//...

$kommando->execute();
     include("dbtrennung.php");
     echo"<p>Die Daten wurden eingetragen.</p>\n";

  
Paradebeispiel :-)  
  
Du vermeldest hier, die Daten seien eingetragen worden - aber \*ueberprueft\* hast du das nicht.  
  

> Und das funktioniert. Hab ich Dich richtig verstanden, daß ich es nicht dabei belassen soll, daß es funktioniert sondern daß es einen guten Programmierer [1] auszeichnet, jetzt \_totzdem\_ Überprüfungen zu machen.  
  
Das unterscheidet nicht nur den "guten" Programmierer von anderen - sondern letztendlich auch den zufriedenen Benutzer von einem enttaeuschten. Du vermeldest, "die Daten wurden eingetragen", aber wir nehmen mal an, das haette nicht geklappt (ueberprueft haben wir es ja noch nicht) - dann will der Benutzer sich jetzt seinen neuen Datensatz anzeigen lassen, aber der ist nirgendwo zu finden - "Hey, aber mir wurde doch gesagt, Daten wurden eingetragen ...?"  
  

> Und wenn ja, wie würdest Du da vorgehen jetzt?  
  
Du hast $kommando->execute() aufgerufen, um die INSERT-Query, die zunaechst prepared und dann auch mit Daten versorgt(bind\_param( wurde, jetzt auch von der Datenbank ausfuehren zu lassen.  
  
Auch dabei koennen noch Dinge schief gegangen sein. Syntaktische Fehler kann unsere Query jetzt zwar nicht mehr enthalten - das waere uns beim prepare-n des Statements aufgefallen (wie im vorliegenden Fall, falschen Tabellennamen angegeben). Aber es koennte zum Beispiel sein, dass auf der Spalte 001\_name in der Definition in der Datenbank ein "unique Index" liegt, weil jeder Name nur einmal eingetragen werden koennen soll.  
Waere der Name, den der Benutzer einzutragen versucht, schon vorhanden, dann \*muss\* diese Query, die ihn erneut einzutragen versucht, also schief gehen.  
  
Schauen wir uns also wieder im Handbuch an, was die [execute](http://www.php.net/manual/en/mysqli-stmt.execute.php)-Methode des MySQLi\_STMT-Objektes uns ueber ihren Rueckgabewert mitzuteilen hat:  
"Returns TRUE on success or FALSE on failure."  
  
Auch das koennen wir also wieder recht simpel auswerten, z.B. a la  
~~~php
if(!$kommando->execute()) {  
  echo "<p>Tut uns leid, da trat leider ein Fehler auf!<p>\n";  
}  
else {  
  echo "<p>Die Daten wurden eingetragen.</p>\n";  
}

Welcher Fehler das war, weiss der Benutzer damit noch nicht.
Die genaue Meldung der Datenbank wuerden *wir*, die Programmierer, uns jetzt wieder mittels $kommando->error ausgeben lassen. Das ist dann aber wieder sowas technisches, noch dazu Englisches - das wollen wir dem Benutzer nicht zumuten.

Wenn wir dem Benutzer jetzt aber noch den Grund mitteilen wollten, dass es hier daran lag, dass er Name, den er eintragen wollte, schon vorhanden war - dann koennten wir auch $kommando->errno auswerten. Das liefert uns eine Fehler*nummer*, und auch die sind irgendwo dokumentiert. Das wuerden wir dann ueberpruefen, ob das die Nummer ist, die bei einem solchen Fehler gemeldet wird - und dann koennten wir den Benuzter auch darauf noch explizit hinweisen, dass es im konkreten Fall daran lag, dass der Name schon vorhanden ist ...

MfG ChrisB

--
„This is the author's opinion, not necessarily that of Starbucks.“