Warum erhalte ich den Fehler Cannot pass parameter 2 by reference, wenn ich bindParam mit einem konstanten Wert verwende?
Lesezeit: 5 Minuten
Nacho
Ich verwende diesen Code und bin mehr als frustriert:
try {
$dbh = new PDO('mysql:dbname=" . DB . ";host=" . HOST, USER, PASS);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES "utf8'");
}
catch(PDOException $e)
{
...
}
$stmt = $dbh->prepare('INSERT INTO table(v1, v2, ...) VALUES(:v1, :v2, ...)');
$stmt->bindParam(':v1', PDO::PARAM_NULL); // --> Here's the problem
PDO::PARAM_NULL, null, '', alle scheitern und werfen diesen Fehler:
Fataler Fehler: Parameter 2 kann nicht als Referenz in /opt/… übergeben werden
JasonWoof
Sie müssen verwenden bindValuenicht bindParam
bindParam nimmt eine Variable als Referenz und zieht zum Zeitpunkt des Aufrufs keinen Wert ein bindParam. Ich habe dies in einem Kommentar zu den PHP-Dokumenten gefunden:
bindValue(':param', null, PDO::PARAM_INT);
PS Sie könnten versucht sein, dies zu tun bindValue(':param', null, PDO::PARAM_NULL); aber es hat nicht bei allen funktioniert (danke Will Shaver für die Meldung.)
Ich bin mir nicht sicher, was der Unterschied zwischen diesen beiden ist, aber ich werde einige untersuchen. Danke, deine Antwort war auch super.
– Nacho
8. September 2009 um 3:29 Uhr
Ich denke, das könnte eine bessere Antwort sein als meine (wenn es tatsächlich funktioniert)
– Joe Phillips
4. März 2010 um 19:51 Uhr
Ich hatte Probleme mit PDO::PARAM_NULL auf MySql 5.1.53, aber PDO::PARAM_INT mit einem Nullwert hat super funktioniert.
– Will Shaver
5. Dezember 2011 um 19:33 Uhr
Odin: Ich denke, der wichtigste Teil ist, alle drei Parameter zu übergeben :). In der Frage von ign übergab er PDO::PARAM_NULL als Wert und nicht als Typ (und übergab überhaupt keinen Typ.)
– JasonWoof
17. Dezember 2011 um 9:30 Uhr
FYI: In den meisten Fällen ist die Verwendung völlig in Ordnung bindValue() über bindParam(); für alles, nicht nur für die NULL Wert. Mir fällt kein einziger Fall ein, in dem Sie den Parameter an eine Referenz einer PHP-Variablen binden müssten – aber das ist was bindParam() tut.
– niedrige_mieten
3. Dezember 2015 um 10:17 Uhr
Joe Phillips
Beim Benutzen bindParam() Sie müssen eine Variable übergeben, keine Konstante. Also müssen Sie vor dieser Zeile eine Variable erstellen und auf setzen null
Sie würden dieselbe Fehlermeldung erhalten, wenn Sie Folgendes versuchen würden:
$stmt->bindParam(':v1', 5, PDO::PARAM_NULL);
Das hast du richtig verstanden, mir ist gerade aufgefallen, dass ich das schon einmal in meinem Code gemacht hatte, $null = PDO::PARAM_NULL; Danke.
– Nacho
8. September 2009 um 3:31 Uhr
Es ist besser, in diesem Fall bindValue() zu verwenden, wenn Sie sowieso Platzhalter erstellen möchten. bindParam() ist ursprünglich dazu gedacht, eine Abfrage auszuführen und dann die Variablen zu ändern und erneut auszuführen, ohne die Parameter erneut zu binden. bindValue() bindet sofort, bindParam() nur beim Ausführen.
– Hugo Zink
7. Oktober 2015 um 8:49 Uhr
Ich habe festgestellt, dass null in der Zeile $myNull = null kleingeschrieben werden muss. $myNull = NULL hat NICHT funktioniert.
– Raphael75
28. November 2017 um 15:11 Uhr
Beim Benutzen INTEGER Spalten (das kann sein NULL) in MySQL hat PDO ein (für mich) unerwartetes Verhalten.
Wenn du benutzt $stmt->execute(Array)müssen Sie das Literal angeben NULL und kann nicht geben NULL durch Variablenbezug. Das wird also nicht funktionieren:
// $val is sometimes null, but sometimes an integer
$stmt->execute(array(
':param' => $val
));
// will cause the error 'incorrect integer value' when $val == null
Aber das wird funktionieren:
// $val again is sometimes null, but sometimes an integer
$stmt->execute(array(
':param' => isset($val) ? $val : null
));
// no errors, inserts NULL when $val == null, inserts the integer otherwise
Versucht dies auf MySQL 5.5.15 mit PHP 5.4.1
$stmt->execute(array( ‘:param’ => !empty($val) ? $val : null )); Verwenden Sie !empty, da Sie für eine leere Zeichenfolge auch null in der Datenbank festlegen möchten
– Shehzad Nizamani
30. Juni 2017 um 19:36 Uhr
@ShehzadNizamani Nur wenn der Spaltentyp wie in seinem Beispiel ganzzahlig ist, ja. Aber sonst isset() korreliert besser mit NULL. Ein leerer String ist auch ein Wert.
– StanE
17. November 2017 um 2:25 Uhr
@ShehzadNizamani was ist mit 0 Wert? empty() gibt dafür true zurück. und Ihr Code speichert null anstelle eines legitimen 0-Ganzzahlwerts
– Ihr gesunder Menschenverstand
13. Februar 2021 um 8:00 Uhr
Für diejenigen, die immer noch Probleme haben (Parameter 2 kann nicht als Referenz übergeben werden), definieren Sie eine Variable mit Nullwert und übergeben Sie nicht nur Null an PDO:
bindValue(':param', $n = null, PDO::PARAM_INT);
Hoffe das hilft.
Ich hatte das gleiche Problem und fand diese Lösung mit bindParam :
Wenn Sie einfügen möchten NULL erst wenn die value ist empty oder ''aber fügen Sie die ein value wenn es verfügbar ist.
A) Empfängt die Formulardaten mit der POST-Methode und ruft die Funktion insert mit diesen Werten auf.
insert( $_POST['productId'], // Will be set to NULL if empty
$_POST['productName'] ); // Will be to NULL if empty
B) Wertet aus, ob ein Feld vom Benutzer nicht ausgefüllt wurde, und fügt es ein NULL wenn das der Fall ist.
public function insert( $productId, $productName )
{
$sql = "INSERT INTO products ( productId, productName )
VALUES ( :productId, :productName )";
//IMPORTANT: Repace $db with your PDO instance
$query = $db->prepare($sql);
//Works with INT, FLOAT, ETC.
$query->bindValue(':productId', !empty($productId) ? $productId : NULL, PDO::PARAM_INT);
//Works with strings.
$query->bindValue(':productName',!empty($productName) ? $productName : NULL, PDO::PARAM_STR);
$query->execute();
}
Wenn der Benutzer zum Beispiel nichts auf dem eingibt productName Feld des Formulars, dann $productName wird sein SET aber EMPTY. Sie müssen also prüfen, ob dies der Fall ist empty()und wenn ja, dann einfügen NULL.
Getestet auf PHP 5.5.17
Viel Glück,
Vinzenz
Basierend auf den anderen Antworten, aber mit etwas mehr Klarheit darüber, wie diese Lösung tatsächlich verwendet wird.
Wenn Sie beispielsweise einen leeren String für einen Zeitwert haben, ihn aber als Null speichern möchten: