我很想知道是否可以使用pdo将值数组绑定到占位符。这里的用例试图传递一个值数组,以便与 IN()
条件。
我希望能够做到这样:
<?php
$ids=array(1,2,3,7,8,9);
$db = new PDO(...);
$stmt = $db->prepare(
'SELECT *
FROM table
WHERE id IN(:an_array)'
);
$stmt->bindParam('an_array',$ids);
$stmt->execute();
?>
让pdo绑定并引用数组中的所有值。
目前我正在做:
<?php
$ids = array(1,2,3,7,8,9);
$db = new PDO(...);
foreach($ids as &$val)
$val=$db->quote($val); //iterate through array and quote
$in = implode(',',$ids); //create comma separated list
$stmt = $db->prepare(
'SELECT *
FROM table
WHERE id IN('.$in.')'
);
$stmt->execute();
?>
这当然可以,但只是想知道是否有一个内置的解决方案,我错过了?
21条答案
按热度按时间pes8fvy91#
因为我做了很多动态查询,所以这是我做的一个超级简单的助手函数。
像这样使用:
返回字符串
:id1,:id2,:id3
同时更新您的$bindArray
运行查询时所需的绑定。容易的!a11xaf1n2#
首先在查询中设置“?”的数量,然后通过“for”发送如下参数:
sg24os4d3#
在经历了同样的问题之后,我找到了一个更简单的解决方案(尽管仍然不如一个简单的解决方案优雅)
PDO::PARAM_ARRAY
可能是):给定数组
$ids = array(2, 4, 32)
:... 等等
因此,如果使用的是混合值数组,则在指定类型param之前,需要更多的代码来测试值:
但我没有测试过这个。
v09wglhw4#
为了让答案更接近使用占位符绑定参数的原始问题,我做了进一步的工作。
这个答案必须在查询中使用的数组中进行两个循环。但它确实解决了在更具选择性的查询中使用其他列占位符的问题。
hfsqlsce5#
在pdo中不可能使用这样的数组。
您需要为每个值构建一个带有参数(或使用?)的字符串,例如:
:an_array_0, :an_array_1, :an_array_2, :an_array_3, :an_array_4, :an_array_5
举个例子:如果你想继续使用
bindParam
,您可以这样做:如果你想用
?
占位符,您可以这样做:如果你不知道
$ids
如果为空,则应该测试它并相应地处理该情况(返回空数组,或返回空对象,或引发异常,…)。xcitsw886#
当您有其他参数时,您可以这样做:
nhhxz33t7#
对我来说,更性感的解决方案是构造一个动态关联数组并使用它
i86rm4rw8#
使用它有那么重要吗
IN
声明?尝试使用FIND_IN_SET
作品。例如,在pdo中有这样一个查询
然后您只需要绑定一个值数组,用逗号内爆,就像这个
一切都结束了。
upd:正如一些人在对这个答案的评论中指出的那样,有一些问题需要明确说明。
FIND_IN_SET
没有在表中使用索引,它还没有实现-请参阅mysql bug tracker中的记录。感谢@billkarwin的通知。不能使用内部带有逗号的字符串作为搜索数组的值。用正确的方法解析这样的字符串是不可能的
implode
因为您使用逗号符号作为分隔符。感谢@val的留言。总之,如果您不严重依赖索引,也不使用带逗号的字符串进行搜索,那么我的解决方案将比上面列出的解决方案更简单、更快速。
xxls0lw89#
快来点东西:
lxkprmvk10#
如果列只能包含整数,则可以不使用占位符,直接将id放入查询中。您只需将数组的所有值强制转换为整数。这样地:
这不应该受到任何sql注入的攻击。
mqkwyuun11#
你在用什么数据库?在postgresql中,我喜欢使用any(数组)。因此,要重用您的示例:
不幸的是,这是相当不便携。
在其他数据库上,您需要像其他人所提到的那样构建自己的魔力。当然,您需要将该逻辑放入类/函数中,以使其在整个程序中可重用。看一下关于
mysql_query
请访问php.net上的页面,了解有关该主题的更多想法和此场景的示例。daupos2t12#
我认为Solr默是对的。您必须构造查询字符串。
菲克斯:丹,你说得对。修复了代码(但没有测试)
编辑:chris(评论)和somebodyisintrouble都建议foreach循环。。。
... 可能是多余的,所以
foreach
环路和$stmt->execute
可能会被。。。(再说一遍,我没有测试)
klr1opcd13#
这是我的解决办法。我还扩展了pdo类:
以下是上述代码的示例用法:
让我知道你的想法
yyhrrdl814#
postgres非常简洁的方法是使用postgres数组(“{}”):
fbcarpbf15#
邪恶的解决方案对我不起作用。在postgres中,你可以做另一种解决方法: