MySQL MATCH AGAINST全文搜索结合PHP PDO动态绑定参数失效问题
我来帮你解决这个PDO绑定参数导致FULLTEXT搜索失效的问题!
首先得搞清楚问题出在哪:你的静态SQL语句能正常工作,是因为MySQL在布尔模式下会忽略开头的*,实际是在搜索psico这个关键词;但动态绑定参数时,你把带*的字符串直接传给MySQL,它会把整个字符串(包括星号)当作一个完整的词来匹配,而不是把星号解析成通配符,自然搜不到结果。另外你第三种写法里,把参数占位符:query用单引号包起来了,PDO根本不会把它识别为参数,而是直接搜索字符串:query,当然也没结果。
下面给你两种针对性的解决方案,根据你的需求选:
情况1:匹配包含搜索词的任意行(和你原来静态语句效果一致)
MySQL的FULLTEXT布尔模式默认就会匹配包含目标词的行,不需要额外加星号,直接绑定搜索词即可:
$searchTerm = $data['query']; $stmt = $this->db->prepare(" SELECT autocomplete_search_name as label, url as the_link FROM product WHERE status = 'active' AND MATCH(autocomplete_search_name) AGAINST(:query IN BOOLEAN MODE) ORDER BY MATCH(autocomplete_search_name) AGAINST(:query) DESC LIMIT 10 "); $stmt->bindParam(':query', $searchTerm); $stmt->execute(); $moddados = $stmt->fetchAll(); return $moddados;
情况2:匹配以搜索词开头的前缀(比如搜psico能找到psicologia、psicologo这类词)
只需要在搜索词末尾加星号(MySQL布尔模式里星号只能作为后缀通配符),再绑定参数:
$searchTerm = $data['query'] . '*'; $stmt = $this->db->prepare(" SELECT autocomplete_search_name as label, url as the_link FROM product WHERE status = 'active' AND MATCH(autocomplete_search_name) AGAINST(:query IN BOOLEAN MODE) ORDER BY MATCH(autocomplete_search_name) AGAINST(:query) DESC LIMIT 10 "); // 处理字符串时用bindValue有时候比bindParam更可靠 $stmt->bindValue(':query', $searchTerm, PDO::PARAM_STR); $stmt->execute(); $moddados = $stmt->fetchAll(); return $moddados;
再总结下你之前写法失效的原因:
- 第一种写法:把
*psico*作为完整参数绑定,MySQL将星号视为普通字符,不是通配符 - 第二种写法:用
CONCAT拼接出*psico*,结果还是被当作完整词,星号不生效 - 第三种写法:SQL里的
:query被单引号包裹,PDO不会识别为参数,直接搜索字符串:query
内容的提问来源于stack exchange,提问作者Rangel Bacher
相关产品推荐
相关产品推荐

