关于PHP PDO的Bind与Execute:哪种方式可正确防范SQLi?
在PHP PDO中防范SQL注入:绑定参数vs直接Execute
嘿,这个问题问到点子上了——SQL注入是PHP开发里最容易踩的安全大坑,搞清楚PDO里的正确姿势太重要了。
直接给结论:只有使用参数绑定的方式(不管是用bindParam/bindValue,还是直接在execute里传参数数组)才能有效防范SQL注入,而直接把用户输入拼进SQL语句再执行,哪怕调用了execute,也完全不安全。
下面具体拆解两种情况:
安全的方式:参数绑定
不管用哪种绑定形式,核心逻辑都是让数据库先编译SQL模板,再把用户输入作为纯数据传入,数据库不会把参数解析成SQL代码的一部分,从根源上阻断注入可能。
举几个常见的正确写法:
使用
bindParam绑定位置参数:$userInput = $_POST['username']; // 假设这是用户输入 $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?"); $stmt->bindParam(1, $userInput); // 绑定第一个位置的参数 $stmt->execute();使用
bindValue绑定命名参数:$userInput = $_POST['username']; $stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username"); $stmt->bindValue(':username', $userInput); // 绑定命名参数 $stmt->execute();直接在
execute里传入参数数组(最简洁的写法):$userInput = $_POST['username']; $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?"); $stmt->execute([$userInput]); // 直接把参数数组传给execute
额外提醒:最好手动关闭PDO的模拟预处理功能,避免PHP层面拼接参数带来的风险,代码如下:
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
危险的方式:直接拼接用户输入到SQL
如果像下面这样把用户输入直接拼进SQL字符串,哪怕调用了execute,也会被SQL注入攻击:
// 绝对不要这么写!!! $userInput = $_POST['username']; $stmt = $pdo->prepare("SELECT * FROM users WHERE username = '$userInput'"); $stmt->execute();
比如用户输入' OR 1=1 --,这条SQL就会变成SELECT * FROM users WHERE username = '' OR 1=1 --',数据库会执行这个恶意拼接后的语句,直接返回所有用户数据,甚至可能被篡改数据库。
内容的提问来源于stack exchange,提问作者adi pslr
相关产品推荐
相关产品推荐

