PHP PDO 必须启用 PDO::ERRMODE_EXCEPTION 模式并统一异常处理,禁止静默模式;需封装基类转换 PDOException 为业务异常,按错误码分类处理,事务中须显式 rollback 后重抛。
PHP PDO 的错误处理不该依赖默认的静默模式,必须主动配置异常模式并统一捕获逻辑,否则 SQL 错误会被忽略,调试困难,线上问题难以定位。
启用 PDO::ERRMODE_EXCEPTION 模式
PDO 默认使用
,出错只设错误码不抛异常,极易遗漏。务必在创建 PDO 实例后立即设置为异常模式:
连接时直接传入选项:
或连接后显式设置:
避免仅靠
包裹 query/execute —— 若未开启异常模式,这些方法失败也不会触发 catch
封装统一的数据库操作基类
避免每个 DAO 方法都写重复的 try/catch。建议抽象一个基础 DB 类,集中处理异常转换与日志记录:
所有执行方法(
、
+
)都在内部包裹 try/catch
捕获
后,根据错误码(
或
)区分是 SQL 语法错误、唯一键冲突、连接超时等
将底层 PDO 异常转为自定义业务异常(如
、
),便于上层分类处理
区分错误类型,避免裸抛 PDOException
直接把 PDOException 暴露给前端或调用方是危险的,既泄露数据库结构,又混杂了系统级和业务级问题:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
立即学习
“
PHP免费学习笔记(深入)
”;
连接类错误
(如 1045、2002):应标记为系统异常,触发告警,不可重试或需降级
约束类错误
(如 1062 主键/唯一冲突、1452 外键失败):通常是业务校验缺失,应转为用户可读提示(如“手机号已被注册”)
语法/参数类错误
(如 1064、HY093):属开发阶段问题,不应上线,可通过单元测试+预编译检查提前拦截
记录完整错误信息(SQL、绑定参数、堆栈)到日志,但响应体中只返回安全摘要
事务中必须显式 rollback 并重新抛出
事务内发生异常时,仅靠 catch 不足以保证数据一致性:
在 catch 块中第一件事是
,防止连接复用时残留未提交状态
rollback 后仍需
或抛出自定义异常,确保事务边界清晰、调用方能感知失败
避免在 finally 中 commit/rollback —— 会掩盖原始异常,且逻辑不可控
PDO::ERRMODE_SILENTnew PDO($dsn, $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION])$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)try/catchqueryprepareexecutePDOException$e->getCode()$e->errorInfo[1]DbQueryExceptionDuplicateEntryException$pdo->rollback()throw $e