Php 将内爆数组绑定到mysql准备语句时出现问题
我正在为下面的语法错误绞尽脑汁。我试图将一个内爆数组绑定到一个准备好的语句中,但出现以下语法错误: 您的SQL语法有错误;检查与MySQL服务器版本对应的手册,以了解第1行“?”附近使用的正确语法 这是我的密码。谁能看出我错在哪里Php 将内爆数组绑定到mysql准备语句时出现问题,php,mysql,mysqli,prepared-statement,Php,Mysql,Mysqli,Prepared Statement,我正在为下面的语法错误绞尽脑汁。我试图将一个内爆数组绑定到一个准备好的语句中,但出现以下语法错误: 您的SQL语法有错误;检查与MySQL服务器版本对应的手册,以了解第1行“?”附近使用的正确语法 这是我的密码。谁能看出我错在哪里 <?php include('config.php'); $selected = $_POST['selected']; if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE
<?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();
?>
这给了我正确的答案
('me@me.com', 'you@you.com')
让我给你省点麻烦,告诉你你想做的事无论如何都行不通。您只将一个参数绑定到()中的
函数调用。您认为传递的是一个逗号分隔的列表,但实际上只传递一个逗号分隔的字符串,该字符串被视为一个值。这意味着您将搜索一条值为“”的记录me@me.com', 'you@you.com“,而不是匹配的记录”me@me.com“或”you@you.com“
要克服这一问题,您需要:
$types = str_repeat('s', count($selected));
所做的一切就是创建一个s
字符串,其字符数与数组中的元素数相同
然后,您可以像这样使用call\u user\u func\u array()
绑定参数(注意,我为in()
函数放回了括号):
但是,如果您尝试此操作,您将得到一个关于mysqli_stmt::bind_param()
期望通过引用传递参数2的错误:
警告:mysqli_stmt::bind_param()的参数2应为引用,给定值
这有点烦人,但很容易解决。要解决此问题,您可以使用以下功能:
if ($stmt = $mysqli->prepare("DELETE FROM email_addresses WHERE email_addresses IN (?)")) {
call_user_func_array(array($stmt, "bind_param"), array_merge($types, $selected));
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);
对不起,我没有答案。我只是想说,我认为这是一个巧妙的伎俩。我自己也可以在动态绑定中使用这种技术好几次。@LeeLoftiss请看我的答案,为什么这样做不起作用我的意思是我经常想要动态绑定,但我从来没有想到会有一种方法。我经常忘记PHP的多功能性。下次我需要这个时,我会把你的答案加入书签。谢谢。回答得很好,非常感谢你的解释。我不再收到任何MySQL错误,但由于某种原因,电子邮件地址不会从数据库中删除。我想知道,它们是否需要被引语包围,因为它们是字符串?不需要。引号仅用于解释语句。用于准备不需要的报表。如果您有权访问查询日志,则可以查看SQL查询并验证它是否正确,并将其用于测试。我希望mysqli提供了一种运行查询的方法,但显然没有人认为这是一种有用的功能。不幸的是,我没有。我在一个由GoDaddy托管的客户网站上工作。我相信我会弄明白的,这只是一个多久的问题!希望这能让你更亲近。祝你好运如果您注意到这段代码中有一些需要改进的地方,请告诉我,这样我就可以为以后偶然发现这段代码的其他人发布。答案解释得很好,John。谢谢你能解释一下$types变量吗。
$stmt->bind_param($types, ...$selected);