使用PDO预处理语句可有效防止SQL注入,核心是通过参数化查询将用户输入与SQL逻辑分离,避免恶意代码执行。

使用PDO防止SQL注入是PHP安全编程中的核心技能。关键在于预处理语句(Prepared Statements)的正确使用。PDO本身并不能自动防止SQL注入,只有配合参数化查询才能真正起到防护作用。
什么是SQL注入?
SQL注入是指攻击者通过在输入中插入恶意SQL代码,改变原有查询逻辑,从而获取、篡改或删除数据库数据。例如用户输入 ' OR 1=1 -- 可能绕过登录验证。使用PDO预处理语句防止注入
真正的防护来自于将用户输入与SQL语义分离。PDO的预处理机制可以做到这一点:- 命名占位符方式:使用 :name 形式绑定参数
- 问号占位符方式:适用于位置固定的参数
$pdo = new PDO($dsn, $user, $pass);
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->bindParam(':email', $userEmail, PDO::PARAM_STR);
$stmt->execute();
$stmt = $pdo->prepare("SELECT id, name FROM users WHERE age > ? AND status = ?");
$stmt->execute([$minAge, $status]);
注意:不要拼接变量到SQL字符串中,即使用了quote()也不够安全。唯一可靠的方式是占位符 + execute传参。
避免常见错误用法
以下做法看似使用了PDO,但仍存在风险:- 错误:直接拼接变量
$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];
即使用了PDO::query()也危险。 - 错误:仅使用quote()而不使用预处理
虽然 $pdo->quote() 可转义字符串,但易出错且不推荐用于构建完整查询。 - 正确做法始终是 prepare + execute 分离数据与结构
补充安全建议
除了使用预处理,还需注意:- 对输入进行验证和过滤,如邮箱格式、长度限制
- 最小权限原则:数据库账户只赋予必要权限
- 关闭错误信息显示,避免泄露数据库结构
- 使用UTF-8编码并设置正确的字符集连接
$pdo->exec("SET NAMES utf8");
基本上就这些。只要坚持使用预处理语句,绝大多数SQL注入问题都能避免。
立即学习“PHP免费学习笔记(深入)”;










