正确写法是使用预处理语句,将通配符%拼接到绑定参数值中(如'%' . $keyword . '%'),而非写在sql模板内;需确保字符集为utf8mb4、排序规则支持中文;前导%会导致索引失效,全模糊应改用fulltext或es。

PHP中用LIKE做模糊查询的正确写法
直接拼接用户输入到SQL里是危险的,mysqli_query() 或 pdo->query() 配合 LIKE 时,必须用预处理。常见错误是写成 "%{$_GET['q']}%",这会触发SQL注入。
- 通配符要放在参数值里,不是SQL模板里:绑定时传
'%' . $keyword . '%',而不是在SQL里写LIKE '%?%' - 中文搜索注意数据库和连接的字符集一致,否则可能查不到——检查
SET NAMES utf8mb4是否执行,且表字段是utf8mb4_unicode_ci -
LIKE区分大小写取决于字段排序规则(collation),如需不区分,用utf8mb4_general_ci或显式加LOWER()函数包裹字段和参数
PDO预处理实现安全模糊搜索的最小示例
这是能直接跑通、不漏掉关键步骤的写法:
$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
<p>$keyword = $_GET['q'] ?? '';
$stmt = $pdo->prepare("SELECT id, title FROM article WHERE title LIKE ?");
$stmt->execute(['%' . $keyword . '%']);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
</p>
注意:charset=utf8mb4 必须出现在DSN里;PDO::ATTR_ERRMODE 要设为异常模式,否则错误静默失败;execute() 的参数是数组,即使只有一个值也要包一层 []。
什么时候不该用LIKE——性能与替代方案
当数据量超过10万行,LIKE '%关键词%' 会全表扫描,索引失效。这时要考虑:
- 前缀匹配(
LIKE '关键词%')可走B-tree索引,但中间或后缀匹配不行 - 需要全文检索语义(比如相关性排序、同义词),应改用 MySQL 的
MATCH() AGAINST(),前提是字段建了 FULLTEXT 索引 - 更复杂的场景建议接入 Elasticsearch 或 Meilisearch,PHP端用 HTTP 请求对接,别硬扛
MySQL中LIKE的转义问题怎么处理
如果用户搜的内容含 % 或 _(比如查文件名 report_2024.sql),默认会被当成通配符。解决方式是显式指定 ESCAPE 字符:
SELECT * FROM logs WHERE content LIKE '%report_2024%' ESCAPE '';
对应PDO写法:
$stmt = $pdo->prepare("SELECT * FROM logs WHERE content LIKE ? ESCAPE ?");
$stmt->execute(["%report_2024%", '\']);
注意:反斜杠在PHP字符串里要双写 '\',且必须在绑定时传入,不能写死在SQL里——否则换数据库就挂。
模糊查询真正难的不是语法,而是边界情况:空输入、超长输入、特殊字符、编码错位、索引没生效却以为查得慢是代码问题。这些地方一漏,线上就出数据或安全问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











