php中用pdo执行like模糊查询必须将%拼入绑定参数值中,不可写在sql字符串里;%匹配零或多个字符,前导%会导致索引失效。

PHP中用PDO执行LIKE模糊查询要加百分号
PHP本身没有“模糊查询”语法,LIKE 是 SQL 标准操作符,必须由数据库引擎执行。常见错误是只写 WHERE name LIKE '张',结果查不到任何数据——因为没加通配符。% 才是模糊匹配的关键,它代表零个或多个任意字符。
用 PDO 时,参数绑定不能把 % 写进 SQL 字符串里(比如 "WHERE name LIKE '%?%'"),这会直接报错或被当成字面量。正确做法是把 % 拼到 PHP 变量里,再绑定:
$keyword = $_GET['q'] ?? '';
$keyword = trim($keyword);
$stmt = $pdo->prepare("SELECT * FROM users WHERE name LIKE ?");
$stmt->execute(['%' . $keyword . '%']);
- 用户输入
张→ 实际查的是%张%,匹配“张三”“李张峰”“王小张” - 如果只想查前缀(如“张开头”),用
$keyword . '%';后缀就用'%' . $keyword - 记得对输入做
trim(),避免前后空格导致查不到 - 不推荐用字符串拼接 SQL(如
"... LIKE '%$keyword%'"),有 SQL 注入风险
MySQL中LIKE区分大小写吗?要看字段排序规则
默认情况下,LIKE 是否区分大小写,取决于字段的 collation(排序规则)。比如 utf8mb4_general_ci 中的 _ci 表示 case-insensitive(不区分大小写),而 utf8mb4_bin 或 _cs(case-sensitive)就会区分。
执行 SHOW CREATE TABLE users 就能看到字段定义里的 collation。如果发现模糊查询漏掉大小写变体(比如搜 php 查不到 PHP),大概率是字段用了 _bin 规则。
- 临时解决:在查询里强制转成同一种大小写,例如
WHERE LOWER(name) LIKE LOWER(?) - 长期方案:建表时统一用
utf8mb4_unicode_ci这类常用不区分大小写的 collation - 注意:用函数包裹字段(如
LOWER())会导致索引失效,大数据量时性能明显下降
LIKE查询慢?别硬扛,先看有没有走索引
LIKE '%关键词%' 这种前后都有 % 的写法,MySQL 几乎无法使用 B+ 树索引,只能全表扫描。哪怕加了 name 索引,只要开头是 %,索引就作废。
可以用 EXPLAIN SELECT ... LIKE ... 看 key 和 rows 字段确认是否走索引:
- 如果
key是NULL,说明没走索引 - 如果
rows接近表总行数,基本就是全表扫了 - 前缀匹配(
LIKE '张%')可以走索引,但中间匹配(LIKE '%张%')不行 - 数据量大又必须支持任意位置匹配,考虑用全文索引(
FULLTEXT)或 Elasticsearch
用mysqli_real_escape_string防注入?不如直接用预处理
有人习惯先用 mysqli_real_escape_string() 处理用户输入,再拼进 SQL,比如:
$safe = mysqli_real_escape_string($conn, $_GET['q']); $sql = "SELECT * FROM users WHERE name LIKE '%$safe%'";
这种写法看似安全,但其实有漏洞:mysqli_real_escape_string 对 % 和 _ 不做转义,而这两个正是 LIKE 的通配符。如果用户传入 张_,就可能意外匹配“张三”“张四”甚至“张a”“张9”。
- 真正可靠的方式只有预处理语句(PDO 或 MySQLi 的
prepare/execute) - 如果非要用拼接,至少得手动转义
%和_:str_replace(['%', '_'], ['\%', '\_'], $input),并在 SQL 里加ESCAPE '\' - 但绕来绕去不如一步到位用预处理,代码更短、逻辑更清晰、安全性更高
模糊查询看着简单,实际踩坑点集中在通配符拼接时机、索引失效和大小写行为上。这些不是 PHP 层能绕开的,得结合 SQL 特性和数据结构一起看。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











