2009-09-08 10 views
90

Ich verwende diesen Code und ich bin über Frustration:Wie füge ich NULL-Werte mit PDO ein?

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 von ihnen scheitern und diesen Fehler werfen:

Fatal error: Cannot pass parameter 2 by reference in /opt/...

Antwort

116

ich PDO nur zu lernen, aber ich denke, Sie müssen bindValue verwenden, nicht bindParam

bindParam eine Variable nimmt, zu verweisen und zu der Zeit nicht zu nennen bindParam in einem Wert ziehen. Ich fand dies in einem Kommentar auf der PHP-Dokumentation:

bindValue(':param', null, PDO::PARAM_INT); 

EDIT: P. S. Sie könnten versucht sein, diese bindValue(':param', null, PDO::PARAM_NULL); zu tun, aber es nicht jedermanns Sache funktionierte (danke für die Berichterstattung Rasierapparat Wird.)

+0

Ich bin mir nicht sicher, der Unterschied zwischen diesen beiden, aber ich werde einige untersuchen. Danke, deine Antwort war auch großartig. – Nacho

+3

Ich denke, das könnte eine bessere Antwort sein als meine (wenn es tatsächlich funktioniert) –

+0

meine Tests auf PHP 5.3.8 + Mysql zeigen, dass es keinen Unterschied in der generierten Abfrage zwischen den beiden gibt. Der wichtige Teil scheint zu sein, dass der übergebene Wert NULL ist und nicht '' oder '0' – Odin

42

Wenn bindParam() mit Ihnen in einer Variablen passieren muss, nicht eine Konstante. Also, bevor dieser Linie müssen Sie eine Variable erstellen und ihn auf null

$myNull = null; 
$stmt->bindParam(':v1', $myNull, PDO::PARAM_NULL); 

Sie würden die gleiche Fehlermeldung erhalten, wenn Sie versucht:

$stmt->bindParam(':v1', 5, PDO::PARAM_NULL); 
+0

Sie haben das richtig verstanden, ich erkannte gerade, dass ich es vorher in meinem Code getan hatte, $ null = PDO :: PARAM_NULL; Vielen Dank. – Nacho

+1

In diesem Fall ist es besser, bindValue() zu verwenden, wenn Sie trotzdem Platzhalter machen wollen. bindParam() soll ursprünglich eine Abfrage ausführen und dann die Variablen ändern und erneut ausführen, ohne die Parameter erneut zu binden. bindValue() bindet sofort, bindParam() nur beim Ausführen. –

+0

Ich fand, dass Null in der $ myNull = null Zeile Kleinbuchstaben sein muss. $ myNull = NULL hat nicht funktioniert. – raphael75

24

Wenn INTEGER Spalten mit in MySQL (das NULL sein kann), hat PDO einige (für mich) ein unerwartetes Verhalten .

Wenn Sie $stmt->execute(Array) verwenden, müssen Sie das Literal NULL angeben und NULL nicht durch Variablenreferenz angeben. So wird dies 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 funktioniert:

// $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

+0

$ stmt-> execute (Array ( ': Parameter' =>! Leer ($ val)? $ Val: null )); Verwenden Sie! Empty, weil Sie für eine leere Zeichenfolge auch null in der Datenbank setzen möchten –

+0

@ShehzadNizamani Nur wenn der Spaltentyp eine Ganzzahl ist, wie in seinem Beispiel ja. Aber andererseits korreliert 'isset()' besser mit 'NULL'. Eine leere Zeichenfolge ist auch ein Wert. – StanE

5

Für diejenigen, die immer noch Probleme haben (Parameter 2 kann nicht als Referenz übergeben werden), eine Variable mit Nullwert definieren, nicht nur Null an PDO übergeben:

bindValue(':param', $n = null, PDO::PARAM_INT); 

Hoffe das hilft.

3

Wenn Sie NULL nur einzusetzen, wenn die valueempty oder '' ist, aber die value einzulegen, wenn es verfügbar ist.

A) Erhält die Formulardaten mit der POST-Methode und ruft die Funktion mit diesen Werten auf.

insert($_POST['productId'], // Will be set to NULL if empty  
     $_POST['productName']); // Will be to NULL if empty         

B) Testet, ob ein Feld, das durch den Benutzer nicht gefüllt wurde, und fügt 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();  
} 

Zum Beispiel, wenn der Benutzer nicht alles auf dem productName Bereich der Form, dann werden $productNameSET sein, aber EMPTY. Sie müssen also überprüfen, ob es empty() ist, und wenn dies der Fall ist, fügen Sie NULL ein.

auf PHP Getestet 5.5.17

Viel Glück hatte

+1

Oder Sie können MySQL 'IFNULL()' Funktion in der Abfragezeichenfolge verwenden. So: '$ sql =" INSERT INTO Produkte (productId, productName), VALUES (IFNULL (: productId, NULL), IFNULL (: productName, NULL)) ";' – starleaf1

+0

Ich mag die Sauberkeit Ihrer Lösung. Ich habe es gerade getestet, aber unglücklicherweise fügt es leere Zeichenfolgen anstelle von NULL ein, wenn der Benutzer nichts auf die Eingabe schreibt. Es ist nur eine Frage der Präferenz, aber ich habe lieber NULL statt leere Strings. –

6

ich das gleiche Problem und ich fand diese Lösung mit bindParam arbeiten:

bindParam(':param', $myvar = NULL, PDO::PARAM_INT); 
-1

diesen Versuchen.

+0

Bevor Sie versuchen, eine solche alte Frage zu beantworten, sollten Sie zuerst andere Antworten lesen. Vielleicht ist es schon beantwortet worden. –