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

SQL语法错误时PDOException未被捕获的问题排查

问题原因及解决方案

核心问题:PDO未启用异常模式

你的代码无法进入catch块,是因为PDO默认错误模式不会抛出异常,只会返回错误结果或触发PHP警告。因此query()执行出错时不会抛出PDOException,自然无法被catch捕获。

解决步骤

1. 开启PDO异常模式

在初始化PDO连接的代码中,添加错误模式配置:

// 初始化PDO连接时加入这行设置
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

开启后,PDO执行SQL出错时会主动抛出PDOException,catch块就能正常捕获错误。

2. 修复SQL注入风险(同时解决类型错误问题)

你当前直接拼接$val到SQL的写法存在严重SQL注入漏洞,还会导致id=a这类类型不匹配的错误(数据库会把a解析为列名而非值)。改用预处理语句可同时解决这两个问题:

public function read($tableName, $conditions = []) {
    $con = $this->container->get('connection');
    // 可选:验证表名合法性,防范表名注入风险
    // if (!in_array($tableName, $allowedTables)) { throw new InvalidArgumentException('Invalid table name'); }

    if (empty($conditions)) {
        $query = "SELECT * FROM $tableName";
        $stmt = $con->query($query);
    } else {
        $whereClauses = [];
        $params = [];
        foreach ($conditions as $key => $val) {
            // 使用占位符?替代直接拼接值
            $whereClauses[] = "$key = ?";
            $params[] = $val;
        }
        $where = implode(' AND ', $whereClauses);
        $query = "SELECT * FROM $tableName WHERE $where";
        $stmt = $con->prepare($query);
        // PDO自动处理数据类型绑定与转换
        $stmt->execute($params);
    }
    
    try {
        $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $con = null;
        return $data;
    } catch(PDOException $e) {
        $con = null;
        return [
            'status-code' => 500,
            'error' => $e->errorInfo()[0],
            'message' => $e->getMessage()
        ];
    }
}

补充说明

  • 预处理语句会自动处理值的类型转换,比如把字符串'a'传入数字类型的id字段时,数据库会抛出类型不匹配的异常,该异常会被catch块正常捕获。
  • 永远不要直接拼接用户输入到SQL语句中,预处理是防御SQL注入的标准方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 11:49:54