You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确创建PDO 修复存在SQL注入漏洞的PHP查询代码

PDO改写问题排查与正确实现

原尝试代码的错误点

你写的版本无法正常运行,核心问题如下:

  • 连接实例不匹配:目标为PDO实现,但代码仍用mysqli_connect创建mysqli连接,没有初始化PDO连接对象
  • 变量名拼写错误:定义SQL语句的变量是$query,调用prepare方法时传入的是未定义的$sql变量
  • 参数绑定逻辑错误:bind_param是mysqli扩展的方法,不属于PDO;且绑定顺序、参数类型、传值逻辑完全写反,还错误拼接了用户输入,没有实现预处理防注入的效果
  • 结果集方法混用:取结果时仍调用mysqli系列函数,和PDO预处理返回的结果集不兼容

正确PDO实现代码

<?php
// fetch.php
// 数据库连接配置
$dbHost = 'localhost';
$dbName = 'project';
$dbUser = 'root';
$dbPwd = '';
$dbCharset = 'utf8mb4';

// 初始化PDO连接
try {
    $connect = new PDO(
        "mysql:host=$dbHost;dbname=$dbName;charset=$dbCharset",
        $dbUser,
        $dbPwd,
        [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
        ]
    );
} catch (PDOException $e) {
    die("数据库连接失败:" . $e->getMessage());
}

if (isset($_POST["row_id"])) {
    // 预处理带占位符的SQL语句
    $query = "SELECT id,username,usertype,division,mobnum,userstatus,date(created_at) as created_at FROM users WHERE id = ?";
    $stmt = $connect->prepare($query);
    // 绑定参数,id为整数类型,用PDO::PARAM_INT做类型约束
    $stmt->bindParam(1, $_POST["row_id"], PDO::PARAM_INT);
    $stmt->execute();
    // 获取单条结果并输出json
    $row = $stmt->fetch();
    echo json_encode($row);
}
?>

补充说明

  • 该实现通过PDO预处理机制分离SQL逻辑和用户输入,彻底解决原代码的SQL注入漏洞
  • 若数据库中id字段为字符串类型,将参数绑定的类型改为PDO::PARAM_STR即可
  • 可以简化参数绑定流程,直接在execute方法中传入参数数组,无需单独调用bindParam,写法如下:
    $stmt->execute([$_POST["row_id"]]);
    
  • 初始化PDO时设置的属性默认将结果集返回为关联数组,同时开启异常报错,方便开发阶段排查问题。

内容的提问来源于stack exchange,提问作者edublog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 11:48:27