使用PDO预处理语句实现搜索排除常用词时出错求助
解决数据库搜索排除常用词时的代码错误
我来帮你排查这个问题,你遇到的错误主要来自两个核心问题,咱们一步步拆解:
问题1:占位符与参数数量不匹配
你当前的$params是基于所有搜索词生成的,但$construct里的?占位符只保留了非常用词的部分。比如搜索词是"the flat offers",这三个词都在常用词列表里,那$construct会是空的,但$params还是会生成3个参数,执行SQL时参数数量和占位符数量不匹配,直接触发PDO执行错误。
另外还有个小细节:in_array默认区分大小写,你常用词里有大写的I,但搜索词被转成了小写,导致用户搜i时会被当成非常用词保留,不符合你的预期。
修复步骤和完整代码
咱们针对这两个问题修改代码,同时优化逻辑:
- 单独存储过滤后的有效搜索词,确保占位符和参数数量完全对应
- 把常用词统一转成小写,配合
in_array的严格匹配避免大小写问题 - 处理无有效搜索词的情况,直接返回无结果,避免无意义的全表查询
修复后的完整代码:
$t = strtolower($_POST['e']); // 把常用词统一转成小写,避免大小写匹配偏差 $commonwords = 'a,an,and,i,it,is,do,does,for,from,go,how,the,flat,offers,offer,etc'; $commonwords = explode(",", $commonwords); if (strlen($t) <= 10) { echo ""; } else { $search_exploded = explode(" ", $t); $construct = ''; $valid_terms = []; // 专门存储通过过滤的有效搜索词 foreach ($search_exploded as $search_each) { // 开启严格匹配,确保大小写、类型完全一致 if (!in_array($search_each, $commonwords, true)) { $construct .= "AND d_title LIKE ? "; $valid_terms[] = $search_each; } } // 如果所有搜索词都是常用词,直接返回无结果 if (empty($valid_terms)) { echo "no Result Found"; exit; } include $_SERVER['DOCUMENT_ROOT'] . "/deal/database/db.php"; $query = $con1->prepare("SELECT * FROM deals WHERE 1 $construct ORDER BY `d_id` DESC "); // 仅对有效搜索词生成模糊匹配参数 $params = array_map(function($term) { return "%$term%"; }, $valid_terms); $query->execute($params); $found = $query->rowCount(); if ($found == 0) { echo "no Result Found"; } else { while ($row_de = $query->fetch(PDO::FETCH_ASSOC)) { $de_id = $row_de['d_id']; $de_title = $row_de['d_title']; $d_logo = $row_de['d_logo']; $d_type = $row_de['d_type']; echo $de_title; } } }
额外说明
- 新增的
$valid_terms数组解决了参数和占位符不匹配的核心问题,确保PDO执行时不会报错 - 严格匹配的设置和小写常用词,保证了常用词过滤的准确性
- 提前判断无有效搜索词的场景,既优化了性能,也符合用户的搜索预期
内容的提问来源于stack exchange,提问作者Chetan Kurkure
相关产品推荐
相关产品推荐

