111

我正在使用这段代码,我很沮丧:

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, '',它们都失败并抛出此错误:

致命错误:无法通过 /opt/... 中的引用传递参数 2

4

9 回答 9

144

你需要使用bindValue,而不是bindParam

bindParam通过引用获取变量,并且在调用bindParam. 我在 PHP 文档的评论中发现了这一点:

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

PS您可能很想这样做,bindValue(':param', null, PDO::PARAM_NULL);但它并不适用于所有人(感谢 Will Shaver 的报告。)

于 2009-09-08T03:23:52.733 回答
49

使用bindParam()时必须传入变量,而不是常量。因此,在该行之前,您需要创建一个变量并将其设置为null

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

如果您尝试,您将收到相同的错误消息:

$stmt->bindParam(':v1', 5, PDO::PARAM_NULL);
于 2009-09-08T03:21:58.643 回答
28

在 MySQL 中使用INTEGER列(可以是)时,PDO 有一些(对我而言)意想不到的行为。NULL

如果使用$stmt->execute(Array),则必须指定文字NULL并且不能通过NULL变量引用给出。所以这行不通:

// $val is sometimes null, but sometimes an integer
$stmt->execute(array(
    ':param' => $val
));
// will cause the error 'incorrect integer value' when $val == null

但这会起作用:

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

在 MySQL 5.5.15 和 PHP 5.4.1 上试过这个

于 2012-12-23T13:17:32.163 回答
9

对于那些仍然有问题的人(不能通过引用传递参数 2),定义一个具有 null 值的变量,而不仅仅是将 null 传递给 PDO:

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

希望这可以帮助。

于 2013-09-24T18:27:01.370 回答
5

我遇到了同样的问题,我发现这个解决方案可以与 bindParam 一起使用:

    bindParam(':param', $myvar = NULL, PDO::PARAM_INT);
于 2015-04-21T16:34:02.150 回答
3

如果您只想NULLvalueisempty或时''插入,但在value可用时插入。

A) 使用 POST 方法接收表单数据,并使用这些值调用函数 insert。

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

B) 评估用户是否未填写字段,NULL如果是则插入。

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();      
}

例如,如果用户没有productName在表单的字段上输入任何内容,那么$productName将是SETbut EMPTY。所以,你需要检查它是否是empty(),如果是,然后插入NULL

在 PHP 5.5.17 上测试

祝你好运,

于 2014-10-18T01:28:36.553 回答
0

基于其他答案,但更清楚地了解如何实际使用此解决方案。

例如,如果您有一个空字符串作为时间值,但您想将其保存为空值:

  if($endtime == ""){
    $db->bind(":endtime",$endtime=NULL,PDO::PARAM_STR);
  }else{
    $db->bind("endtime",$endtime);
  }

请注意,对于时间值,您将使用 PARAM_STR,因为时间存储为字符串。

于 2020-03-10T18:31:43.883 回答
-1

就我而言,我正在使用:

  • SQLite,

  • 准备好的带有占位符的语句来处理未知数量的字段,

  • 用户发送的 AJAX 请求,其中所有内容都是字符串,并且没有NULL值和

  • 我迫切需要插入NULLs,因为这不会违反外键约束(可接受的值)。

假设,现在用户使用 post: 发送,$_POST[field1]其值value1可以是空字符串"""null"or "NULL"

首先我声明:

$stmt = $this->dbh->prepare("INSERT INTO $table ({$sColumns}) VALUES ({$sValues})");

我的占位符{$sColumns}在哪里。field1, field2, ...{$sValues}?, ?, ...

然后,我收集$_POST与数组中的列名相关的数据$values 替换为NULLs:

  for($i = 0; $i < \count($values); $i++)
     if((\strtolower($values[$i]) == 'null') || ($values[$i] == ''))
        $values[$i] = null;

现在,我可以执行:

$stmt->execute($values);

以及其他绕过外键约束。

另一方面,如果空字符串确实更有意义,那么您必须检查该字段是否是外键的一部分(更复杂)。

于 2018-11-29T13:45:43.710 回答
-2

试试这个。

$stmt->bindValue(':v1', null, PDO::PARAM_NULL); // --> insert null
于 2017-05-04T01:11:42.737 回答