在使用PDO操作数据库时,LIKE模糊查询是常用的功能,但很多开发者会直接在SQL语句中拼接查询参数,这种方式存在严重的SQL注入风险,正确使用绑定参数才能保障查询安全。
直接拼接参数的安全隐患
如果我们在LIKE语句中直接拼接用户输入的内容,恶意用户可以通过输入特殊字符改变SQL语句的逻辑,比如输入%' OR 1=1 --,就会让查询变成返回所有数据,甚至执行恶意操作。
以下是一个错误的示例:
<?php
// 错误示例:直接拼接参数
$userInput = $_GET['keyword'] ?? '';
$sql = "SELECT * FROM articles WHERE title LIKE '%{$userInput}%'";
$stmt = $pdo->query($sql);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
正确使用绑定参数的方法
PDO的绑定参数功能会把用户输入的内容当作纯字符串处理,不会解析其中的SQL特殊字符,因此需要在拼接好完整的模糊匹配格式后再绑定参数。
使用命名占位符的方式
先构造包含通配符的参数值,再绑定到命名占位符上,这是最常用的方式。
<?php
// 正确示例:命名占位符绑定
$userInput = $_GET['keyword'] ?? '';
// 拼接好通配符,前后都加%表示匹配任意位置包含关键词的内容
$likeParam = "%{$userInput}%";
$sql = "SELECT * FROM articles WHERE title LIKE :keyword";
$stmt = $pdo->prepare($sql);
// 绑定参数,指定参数类型为字符串
$stmt->bindParam(':keyword', $likeParam, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
使用问号占位符的方式
问号占位符的使用逻辑和命名占位符一致,只是占位符形式和绑定方式不同。
<?php
// 正确示例:问号占位符绑定
$userInput = $_GET['keyword'] ?? '';
$likeParam = "%{$userInput}%";
$sql = "SELECT * FROM articles WHERE title LIKE ?";
$stmt = $pdo->prepare($sql);
// 第一个参数是占位符索引,从1开始
$stmt->bindParam(1, $likeParam, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
常见注意事项
- 通配符的拼接需要在绑定参数之前完成,不能把通配符写在SQL语句里再绑定纯用户输入,否则通配符会被当作普通字符处理。
- 如果只需要匹配开头的内容,只需要拼接左侧的
%,比如$likeParam = "{$userInput}%";,匹配结尾则拼接右侧的%。 - 绑定参数时建议显式指定
PDO::PARAM_STR类型,避免自动类型转换带来的问题。 - 即使使用了绑定参数,也不要直接信任用户输入,最好先对输入内容做长度和特殊字符的过滤,进一步降低风险。
错误用法对比
| 错误用法 | 问题说明 |
|---|---|
SQL中写LIKE '%?%'再绑定参数 | 占位符在引号内会被当作普通字符,无法生效,查询会匹配包含?的内容 |
| 直接拼接用户输入到SQL再prepare | prepare阶段就会解析拼接后的SQL,依然有注入风险 |
| 绑定参数时不拼接通配符 | 查询会变成精确匹配,无法实现模糊查询的效果 |
PDO的预处理机制本身是为了分离SQL逻辑和参数值,只要保证参数值是在绑定阶段传入,且SQL语句中没有直接拼接用户输入,就能有效避免SQL注入问题,LIKE语句的使用也遵循这个核心原则。
按照上述方式使用绑定参数,就可以在LIKE语句中既实现模糊查询功能,又保障数据库操作的安全性,避免项目出现SQL注入漏洞。
PDOLIKE语句绑定参数SQL注入prepared_statement修改时间:2026-06-28 11:48:33