[英]Trouble binding an imploded array into a mysql prepared statement
我对以下语法错误感到头疼。 我试图将内爆数组绑定到准备好的语句中,但出现以下语法错误:
您的 SQL 语法有错误; 检查与您的 MySQL 服务器版本相对应的手册,了解在“?”附近使用的正确语法。 在第 1 行
这是我的代码。 谁能看到我哪里出错了?
<?php
include('config.php');
$selected = $_POST['selected'];
if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN ?")) {
$stmt->bind_param("s", "('" . implode("', '", $selected) . "')" );
$stmt->execute();
$stmt->close();
print "ok";
} else {
print $mysqli->error;
}
$mysqli->close();
?>
作为测试,我尝试了:
print "('" . implode("', '", $selected) . "')";
哪个正确地给了我
('me@me.com', 'you@you.com')
让我为您省去一些麻烦,并告诉您您尝试做的事情无论如何都行不通。 您只将一个参数绑定到IN()
函数调用。 您认为您正在传递一个逗号分隔的列表,但实际上您只传递了一个逗号分隔的字符串,该字符串被视为一个 value 。 这意味着你将寻找一个记录,值为“‘me@me.com’,‘you@you.com’”,而不是记录那场比赛“me@me.com”或“you@you.com” .
要克服这个问题,您需要:
call_user_func_array()
绑定参数您可以像这样生成类型字符串:
$types = str_repeat('s', count($selected));
所有这些都是创建一个s
的字符串,它s
字符数与数组中的元素数一样多。
然后你可以像这样使用call_user_func_array()
绑定你的参数(注意我把括号放回IN()
函数):
if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN (?)")) {
call_user_func_array(array($stmt, "bind_param"), array_merge($types, $selected));
但是如果你尝试这个,你会得到一个关于mysqli_stmt::bind_param()
的错误,期望通过引用传递参数二:
警告:mysqli_stmt::bind_param() 的参数 2 应为引用,已给定值
这有点烦人,但很容易解决。 要解决此问题,您可以使用以下函数:
function refValues($arr){
$refs = array();
foreach($arr as $key => $value)
$refs[$key] = &$arr[$key];
return $refs;
}
它只是创建一个值数组,这些值是对$selected
数组中值的引用。 这足以让mysqli_stmt::bind_param()
开心:
if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN (?)")) {
call_user_func_array(array($stmt, "bind_param"), array_merge($types, refValues($selected)));
编辑
从 PHP 5.6 开始,您现在可以使用...
运算符使这更简单:
$stmt->bind_param($types, ...$selected);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.