使用bindParam()为PDO的IN()条件绑定多字符串时无响应问题
解决PDO中绑定数组到IN子句无响应的问题
嘿,我一眼就看出问题所在了——你直接把数组绑定到单个:searchTags占位符,这是PDO不支持的操作!当你这么做的时候,PDO会把整个数组转换成一个字符串(比如变成'extreme,water'或者甚至'Array'),导致你的SQL实际上在找tag等于这个拼接字符串的记录,而不是匹配数组里的任意一个值,自然就查不到结果,看起来像无响应。
下面是正确的解决方法,分两种常用方式:
方法1:使用匿名占位符(最简洁)
首先根据你的数组长度生成对应数量的?占位符,然后直接把数组传给execute():
$searchString = ['extreme', 'water']; // 生成对应数量的占位符,比如两个元素就生成 '?,?' $placeholders = implode(',', array_fill(0, count($searchString), '?')); // 修改SQL语句,把IN(:searchTags)替换成IN(占位符) $sql = "SELECT * FROM posts INNER JOIN post_tags ON posts.id = post_tags.postid INNER JOIN tags ON post_tags.tagid = tags.id WHERE tags.tag IN ( $placeholders ) AND posts.suspended = 0 GROUP BY posts.id"; $results = $db->prepare($sql); // 直接把数组传给execute,PDO会自动按顺序绑定每个值 $results->execute($searchString); // 之后就可以正常获取结果了 $posts = $results->fetchAll(PDO::FETCH_ASSOC);
方法2:使用命名占位符(更清晰)
如果你偏爱命名占位符,可以给每个元素生成独立的命名参数,比如:tag1、:tag2,然后循环绑定:
$searchString = ['extreme', 'water']; $namedPlaceholders = []; foreach ($searchString as $key => $value) { $namedPlaceholders[] = ":tag{$key}"; } $placeholdersStr = implode(',', $namedPlaceholders); $sql = "SELECT * FROM posts INNER JOIN post_tags ON posts.id = post_tags.postid INNER JOIN tags ON post_tags.tagid = tags.id WHERE tags.tag IN ( $placeholdersStr ) AND posts.suspended = 0 GROUP BY posts.id"; $results = $db->prepare($sql); // 循环绑定每个值 foreach ($searchString as $key => $value) { $results->bindValue(":tag{$key}", $value); } $results->execute(); $posts = $results->fetchAll(PDO::FETCH_ASSOC);
额外提示
另外注意一下:如果你的MySQL开启了ONLY_FULL_GROUP_BY模式(默认是开启的),SELECT *配合GROUP BY posts.id可能会报错,因为你查询的列不全在GROUP BY里或者没有用聚合函数。如果遇到这个问题,最好明确指定你需要的列,或者调整GROUP BY子句。
内容的提问来源于stack exchange,提问作者Lachie
相关产品推荐
相关产品推荐

