我正在使用此代码而且我感到非常沮丧:
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。
答案 0 :(得分:128)
我刚学习PDO,但我认为你需要使用bindValue
,而不是bindParam
bindParam
接受变量,引用,并且在调用bindParam
时不会引入值。我在php docs的评论中发现了这个:
bindValue(':param', null, PDO::PARAM_INT);
编辑:P.S。您可能会想要这样做bindValue(':param', null, PDO::PARAM_NULL);
但它并不适用于所有人(感谢Will Shaver报告。)
答案 1 :(得分:46)
使用bindParam()
时,您必须传入变量,而不是常量。因此,在该行之前,您需要创建一个变量并将其设置为null
$myNull = null;
$stmt->bindParam(':v1', $myNull, PDO::PARAM_NULL);
如果您尝试过,则会收到相同的错误消息:
$stmt->bindParam(':v1', 5, PDO::PARAM_NULL);
答案 2 :(得分:26)
在MySQL中使用INTEGER
列(可能是NULL
)时,PDO会有一些(对我而言)意外行为。
如果您使用$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
使用PHP 5.4.1在MySQL 5.5.15上试过这个
答案 3 :(得分:6)
我遇到了同样的问题,我发现这个解决方案使用bindParam:
bindParam(':param', $myvar = NULL, PDO::PARAM_INT);
答案 4 :(得分:5)
对于仍有问题的人(无法通过引用传递参数2),定义一个具有null值的变量,而不只是将null传递给PDO:
bindValue(':param', $n = null, PDO::PARAM_INT);
希望这有帮助。
答案 5 :(得分:3)
如果您只想在NULL
为value
或empty
时插入''
,请在value
可用时插入insert( $_POST['productId'], // Will be set to NULL if empty
$_POST['productName'] ); // Will be to NULL if empty
。
A)使用POST方法接收表单数据,并使用这些值调用函数insert。
NULL
B)评估用户是否填写了某个字段,如果是这种情况,则插入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
字段中输入任何内容,则SET
将为EMPTY
,但empty()
。因此,您需要检查它是NULL
,如果是,请插入{{1}}。
在PHP 5.5.17上测试
祝你好运,答案 6 :(得分:0)
试试这个。
$stmt->bindValue(':v1', null, PDO::PARAM_NULL); // --> insert null
答案 7 :(得分:0)
我正在使用:
SQLite,
带有占位符的准备好的语句,用于处理未知数量的字段,
AJAX请求,其中一切是字符串,并且没有NULL
值和
我迫切需要插入NULL
,因为这不会违反外键约束(可接受的值)。
假设,现在用户发送带有值$_POST[field1]
的帖子value1
,该值可以是空字符串""
或"null"
或"NULL"
。
首先,我发表声明:
$stmt = $this->dbh->prepare("INSERT INTO $table ({$sColumns}) VALUES ({$sValues})");
其中{$sColumns}
就像field1, field2, ...
,而{$sValues}
是我的占位符?, ?, ...
。
然后,我收集与数组$_POST
中的列名相关的$values
数据并替换为NULL
s:
for($i = 0; $i < \count($values); $i++)
if((\strtolower($values[$i]) == 'null') || ($values[$i] == ''))
$values[$i] = null;
现在,我可以执行:
$stmt->execute($values);
以及其他绕过外键约束。
如果另一方面,空字符串确实更有意义,那么您必须检查该字段是否为外键的一部分(更复杂)。
答案 8 :(得分:0)
基于其他答案,但更清楚地说明了如何实际使用此解决方案。
例如,如果您有一个空字符串作为时间值,但您想将其保存为null:
if($endtime == ""){
$db->bind(":endtime",$endtime=NULL,PDO::PARAM_STR);
}else{
$db->bind("endtime",$endtime);
}
请注意,对于时间值,您将使用PARAM_STR,因为时间存储为字符串。