PDO执行无效查询时未输出自定义错误信息反而返回500错误的问题排查
看起来你遇到的问题是,当查询不存在的表时,自定义的错误处理代码没生效,反而直接返回500错误。我帮你拆解下问题根源:
首先,最直接的致命错误是变量名写错了!你在类里定义的数据库连接属性是$this->con,但在错误处理代码里你写成了$this->connect:
print_r($this->connect->errorInfo());
这个$this->connect根本不存在,所以当!$this->sql为真时,PHP会抛出「Undefined property: bb::$connect」的致命错误,直接导致页面返回500,完全没机会执行你想要的错误输出逻辑。把它改成$this->con->errorInfo()就能解决这个最基础的问题。
接下来再深挖一层:为什么!$this->sql这个判断能触发?因为PDO默认是静默错误模式(ERRMODE_SILENT),当prepare语句失败(比如表不存在),$this->con->prepare()会返回false,这时候你的判断逻辑会进入分支。但这里因为变量名写错,反而触发了更严重的致命错误。
另外给你个优化建议:把PDO的错误模式改成异常模式,这样能更优雅、全面地捕获错误,不用依赖手动判断。你可以在构造函数里添加一行配置:
function __construct() { $this->con = new PDO('mysql:host=localhost;dbname=table', 'user', 'pass', [ PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'", PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION // 新增这行开启异常模式 ]); }
开启异常模式后,PDO会在数据库操作出错时自动抛出PDOException异常,你可以用try-catch块统一捕获处理,比如把query方法改成这样:
function query($sql, $value, $type = false) { try { $this->sql = $this->con->prepare($sql); $this->sql->execute($value); return $type ? $this->sql->fetch() : $this->sql->fetchAll(); } catch(PDOException $e) { echo '数据库错误:' . $e->getMessage(); die(); } }
这样不管是prepare阶段还是execute阶段的错误,都能被精准捕获,而且不会出现像之前那样因为笔误导致的二次错误。
最后提个小提醒:开发环境下可以直接输出错误信息方便调试,但生产环境一定要把错误信息隐藏,避免泄露数据库相关的敏感信息。
备注:内容来源于stack exchange,提问作者flex

