导读:本期聚焦于小伙伴创作的《PHP代码如何防止SQL注入攻击?PHP预处理语句与参数绑定技巧有哪些》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《PHP代码如何防止SQL注入攻击?PHP预处理语句与参数绑定技巧有哪些》有用,将其分享出去将是对创作者最好的鼓励。

SQL注入是PHP应用开发中需要重点防范的安全漏洞,攻击者通过在用户输入中插入恶意SQL片段,可能绕过验证逻辑、窃取敏感数据甚至篡改数据库内容。预处理语句配合参数绑定是PHP官方推荐的防注入方案,能有效隔离SQL逻辑与用户输入数据。

PHP代码如何防止SQL注入攻击?PHP预处理语句与参数绑定技巧有哪些

SQL注入的产生原因

当开发者直接将用户输入拼接到SQL语句中执行时,就容易产生注入风险。比如下面的代码就存在明显的安全问题:

<?php
$username = $_POST['username'];
$password = $_POST['password'];
// 直接拼接用户输入到SQL语句,存在注入风险
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
$result = mysqli_query($conn, $sql);
?>

如果攻击者在username输入框中填入admin' --,拼接后的SQL会变成SELECT * FROM users WHERE username = 'admin' --' AND password = 'xxx',--是SQL的注释符,后面的密码验证逻辑会被直接忽略,攻击者无需密码就能登录admin账户。

预处理语句的防注入原理

预处理语句的核心是将SQL语句的结构和数据分开处理:首先向数据库发送带占位符的SQL模板,数据库会对模板进行编译解析,生成执行计划;之后再将用户输入的数据单独发送给数据库,数据库只会把数据当作纯参数处理,不会将其解析为SQL指令的一部分,从根源上避免了注入。

使用mysqli扩展实现预处理与参数绑定

1. 准备预处理语句

使用mysqli_prepare函数创建预处理对象,SQL中的占位符用问号?表示:

<?php
// 假设已经建立了数据库连接$conn
$username = $_POST['username'];
$password = $_POST['password'];
// 带占位符的SQL模板,?是参数占位符
$sql = "SELECT id,username FROM users WHERE username = ? AND password = ?";
// 创建预处理语句对象
$stmt = mysqli_prepare($conn, $sql);
if (!$stmt) {
    die("预处理失败: " . mysqli_error($conn));
}
?>

2. 绑定参数并执行

使用mysqli_stmt_bind_param绑定参数,第一个参数是预处理对象,第二个参数是参数类型字符串,s代表字符串,i代表整数,d代表浮点数,b代表二进制数据,后面依次传入要绑定的变量:

<?php
// 绑定参数,这里两个参数都是字符串类型,所以用ss
mysqli_stmt_bind_param($stmt, "ss", $username, $password);
// 执行预处理语句
mysqli_stmt_execute($stmt);
// 获取结果集
$result = mysqli_stmt_get_result($stmt);
if (mysqli_num_rows($result) > 0) {
    echo "登录成功";
} else {
    echo "用户名或密码错误";
}
// 关闭预处理对象
mysqli_stmt_close($stmt);
?>

使用PDO扩展实现预处理与参数绑定

PDO是PHP更通用的数据库扩展,支持多种数据库,预处理写法更简洁:

<?php
try {
    // 创建PDO连接,这里以MySQL为例
    $pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8", "root", "123456");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $username = $_POST['username'];
    $password = $_POST['password'];
    // 准备预处理语句,也可以用命名占位符:username
    $sql = "SELECT id,username FROM users WHERE username = :username AND password = :password";
    $stmt = $pdo->prepare($sql);
    // 绑定参数并执行,也可以直接在执行时传入参数数组
    $stmt->bindParam(":username", $username, PDO::PARAM_STR);
    $stmt->bindParam(":password", $password, PDO::PARAM_STR);
    $stmt->execute();
    
    // 或者直接execute传入参数数组,无需单独绑定
    // $stmt->execute([':username' => $username, ':password' => $password]);
    
    $user = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($user) {
        echo "登录成功,欢迎" . $user['username'];
    } else {
        echo "用户名或密码错误";
    }
} catch (PDOException $e) {
    die("数据库操作失败: " . $e->getMessage());
}
?>

防注入的额外注意事项

  • 不要相信任何用户输入,所有传入数据库的数据都通过预处理参数绑定处理,即使是内部系统的输入也不能省略这个步骤
  • 数据库连接时设置正确的字符集,比如使用utf8mb4,避免宽字节注入问题
  • 遵循最小权限原则,给数据库连接账号只分配必要的操作权限,即使发生注入也能降低损失
  • 不要将数据库报错信息直接返回给用户,避免泄露数据库结构信息

PHPSQL注入预处理语句参数绑定修改时间:2026-07-19 00:03:27

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。