我正在打破以下语法错误。我试图将一个内爆数组绑定到一个预准备语句,但我得到以下语法错误:
您的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')
答案 0 :(得分:2)
让我省去一些麻烦,并告诉你,你想要做的事情无论如何都行不通。您只将一个参数绑定到IN()
函数调用。您认为您正在传递以逗号分隔的列表,但实际上您只传递一个逗号分隔的字符串,该字符串被视为一个值。这意味着您将搜索一条记录,其值为“'me@me.com”,“you @ you.com”,而不是与“me@me.com”匹配的记录或“you@you.com”。
要解决这个问题,您需要:
call_user_func_array()
绑定参数您可以像这样生成类型字符串:
$types = str_repeat('s', count($selected));
所有这一切都是创建一个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()
期望参数2通过引用传递:
警告:参数2到mysqli_stmt :: bind_param()应该是一个参考,给定值
这有点烦人但很容易解决。要解决此问题,您可以使用以下功能:
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)));