我需要绑定一个数组的值到WHERE IN(?)
子句。我该怎么做呢?
这是可行的:
$mysqli = new mysqli("localhost", "root", "root", "db");
if(!$mysqli || $mysqli->connect_errno)
{
return;
}
$query_str = "SELECT name FROM table WHERE city IN ('Nashville','Knoxville')";
$query_prepared = $mysqli->stmt_init();
if($query_prepared && $query_prepared->prepare($query_str))
{
$query_prepared->execute();
但我无法使用这样的bind_param:
$query_str = "SELECT name FROM table WHERE city IN (?)";
$query_prepared = $mysqli->stmt_init();
if($query_prepared && $query_prepared->prepare($query_str))
{
$cities = explode(",", $_GET['cities']);
$str_get_cities = "'" . implode("', '", $get_cities) . "'"; // This equals 'Nashville','Knoxville'
$query_prepared->bind_param("s", $cities);
$query_prepared->execute();
"我做错了什么"
我也尝试过call_user_func_array
,但似乎无法获得正确的语法。
6条答案
按热度按时间pes8fvy91#
从PHP 8.1开始,您可以直接传递一个数组来执行:
对于早期版本来说,这个任务有点复杂,但是是可行的。对于一个简单的情况,当你已经有了一个带有占位符的查询时,代码应该是
虽然,就像您的例子一样,我们有任意数量的占位符,但我们必须添加更多的代码。我将从我的文章Mysqli prepared statement with multiple values for IN clause中得到解释:
?
标记数与数组中的元素数相同。为此,我们将使用str_repeat()
函数,该函数非常方便。str_repeat()
再次拯救了我们。$stmt->bind_param("s", $array)
,bind_param()
中只允许标量变量。幸运的是,有一个参数解包操作符可以做我们所需要的事情--把一个数组值发送到一个函数中,就好像它是一组不同的变量一样!所以正确的示例代码应该是
尽管这段代码相当大,但它比本主题迄今为止提供的任何其他可行的解决方案都要小得多。
rggaifut2#
对于绑定的每个变量,都需要一个 * 问号 *。
"bind_param"检查每个变量是否符合要求,然后将字符串值放在引号中。
这是行不通的:
它必须是:
$query_prepared->bind_param
将字符串参数逐一引起来,变量个数和字符串类型长度必须与语句中的参数匹配。将成为
现在
bind_param
必须是用这个
和
bind_param
,其中您将获得:
这就是数组不起作用的原因,唯一的解决方案是
call_user_func_array
。如果初始化语句,则无需执行以下操作:
这是正确的:
如果你不想使用
call_user_func_array
,而且你只有少量的参数,你可以用下面的代码来完成。我建议你用
call_user_func_array
来达到。寻找
nick9v
的解。pb3skfrl3#
从PHP 8.1版开始,binding is no longer required .与从5.0版开始的PDO一样,现在可以将参数作为数组直接传递给execute方法。
另一个例子是,如果有一个关联数组,其中的键与列名匹配:
另外值得一提的是now defaults库在出错时抛出异常,在8.1版本之前不是这样的。
vptzau2j4#
像这样使用call_user_func_array:
xqkwcwgp5#
我在这方面也遇到了麻烦,在发现大多数人都在使用call_user_func_array之前,我让它与
eval
一起工作:voase2hg6#
我是这么做的:准备带有所有单独问号的查询,以及类型字符串。
连接。
然后使用"..."标记/省略号(文档)来绑定数组。
我知道这有点违背了绑定的目的,因为它是为了逃逸(但至少它可以很好地处理整数列表,即ID)。