我用pdo来执行一个带有 IN
使用数组作为其值的子句:
$in_array = array(1, 2, 3);
$in_values = implode(',', $in_array);
$my_result = $wbdb->prepare("SELECT * FROM my_table WHERE my_value IN (".$in_values.")");
$my_result->execute();
$my_results = $my_result->fetchAll();
上面的代码运行得非常好,但我的问题是为什么它不能:
$in_array = array(1, 2, 3);
$in_values = implode(',', $in_array);
$my_result = $wbdb->prepare("SELECT * FROM my_table WHERE my_value IN (:in_values)");
$my_result->execute(array(':in_values' => $in_values));
$my_results = $my_result->fetchAll();
此代码将返回 my_value
等于表中的第一项 $in_array
(1) ,而不是数组中的其余项(2和3)。
9条答案
按热度按时间ylamdve61#
由于pdo似乎没有提供一个好的解决方案,您不妨考虑使用dbal,它主要遵循pdo的api,但也添加了一些有用的特性http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#list-参数转换方法
可能还有其他一些包不会增加复杂性,也不会模糊与数据库的交互(像大多数orm一样),但同时会使小的典型任务变得更容易一些。
bf1o4zei2#
使用闭包的php幻觉的另一个版本(@your common sense):
6kkfgxo03#
据我所知,这是因为pdo将把$in_值内容视为一个单独的项目,并相应地修改它。pdo将1、2、3看作一个字符串,因此查询看起来像
从我的\u值所在的表中选择*(“1,2,3”)
你可能认为把内爆改成引号和逗号可以解决这个问题,但事实并非如此。pdo将看到引号并更改它引用字符串的方式。
至于为什么您的查询匹配第一个值,我没有解释。
0ve6wy6x4#
我刚刚遇到这个问题,编写了一个小 Package 器。我敢肯定,这不是最漂亮或最好的代码,但它可能会对某些人有所帮助
e、 g,把这些传过来:
变成:
它不是防弹的,但作为一个唯一的开发我的需要它做的工作很好,到目前为止无论如何。
92dk7w1h5#
下面是一个未命名占位符(?)的解决方案。如果您传递带有问号“a=”的$sql?和b在(?)”和$args中,其中一些元素是数组,如[1,[1,2,3]],它将返回带有适当数量占位符的sql字符串-“a=?和b在(?,?)”中。它只需要$args参数就可以找到哪个元素是数组以及它需要多少占位符。您可以使用此方法找到将运行查询的小型pdo扩展类:https://github.com/vicf/pdo/blob/master/src/pdo.php
6kkfgxo06#
这是我的完整代码,抱歉我愚蠢的编码,糟糕的结构和注解行。也许有人重新编码了我的愚蠢代码:)
发送到班级:
类获取此sql:
类将此sql转换为此sql。
类绑定参数:
代码:
}
eoxn13cs7#
我经常使用find\ in\ u set而不是in,如下所示:
就性能而言,这不是最好的解决方案,但如果$in\数组的可能数量选项受到限制,则通常不是问题。我经常用它来表示我的\值是枚举字段的状态。从来没有任何问题。
wh6knrhe8#
pdo不擅长这样的事情。您需要动态创建一个带有占位符的字符串,并将其插入到查询中,同时以通常的方式绑定数组值。对于位置占位符,它将如下所示:
如果查询中有其他占位符,可以使用以下方法(代码取自我的pdo教程):
你可以用
array_merge()
函数将所有变量联接到一个数组中,并按它们在查询中的显示顺序以数组的形式添加其他变量:在使用命名占位符的情况下,代码会稍微复杂一些,因为您必须创建一个命名占位符序列,例如。
:id0,:id1,:id2
. 所以代码是:幸运的是,对于命名占位符,我们不必遵循严格的顺序,因此可以按任何顺序合并数组。
xam8gpfp9#
pdo prepared语句中的变量替换不支持数组。一对一。
您可以通过根据数组的长度生成所需的占位符数来解决这个问题。