发布于2026-07-02 阅读(0)
扫一扫,手机访问
数据库模糊查询是PHP开发中再常见不过的需求,但很多人写出来的搜索代码在线上总会出点这样那样的小问题。这里有几个实战中容易踩的坑,以及经过验证的正确写法,直接说关键的。
直接拼接用户输入到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 = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$keyword = $_GET['q'] ?? '';
$stmt = $pdo->prepare("SELECT id, title FROM article WHERE title LIKE ?");
$stmt->execute(['%' . $keyword . '%']);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
注意几个细节:`charset=utf8mb4`必须写在DSN里;`PDO::ATTR_ERRMODE`要设为异常模式,否则错误会被静默处理;`execute()`的参数是个数组,即使只有一个值也要用`[]`包起来。
当数据量超过10万行时,`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里——否则换个数据库就可能出问题。
说到底,模糊查询真正难的不是语法,而是那些边界情况:空输入、超长输入、特殊字符、编码错位、索引没生效却以为是代码太慢。这些地方只要漏掉一个,线上就可能出问题。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8