必须关闭错误显示并启用日志记录:设display_errors=Off、log_errors=On、error_log指向可控路径;禁用mysqli_error()和PDO原始错误输出,改用try/catch脱敏处理;框架层关闭debug模式并隔离配置文件。

PHP数据库报错信息泄露不是代码写错了,而是把不该让外界看到的内部结构“主动喊出来”了。核心动作就两件:**不让错误显示给用户,但要让运维看得清清楚楚**。
关闭客户端错误显示
这是第一道防线,必须在生产环境强制关闭:
-
php.ini 中设置:
display_errors = Off(禁止输出到页面或API响应) - 同时确认
log_errors = On,并指定日志路径,例如:error_log = /var/log/php/error.log - 重启 Web 服务(如 Apache 或 PHP-FPM)使配置生效
堵住 mysqli_error() 和 PDO 错误的“后门”
即使 display_errors = Off,代码里显式调用 mysqli_error() 或直接 echo $pdo->errorInfo(),仍会把数据库名、表名、字段甚至 SQL 片段暴露在 AJAX 响应或 HTML 源码中:
- 删除所有类似
echo mysqli_error($conn)或die($e->getMessage())的调试式输出 - PDO 应统一使用异常模式:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION),再用 try/catch 捕获,只记录日志,不返回原始错误 - 自定义异常处理器中,对数据库类异常做脱敏处理,例如将 “Unknown column 'passwrd' in 'field list'” 替换为 “数据查询失败,请稍后重试”
框架层额外加固(以 ThinkPHP/Laravel/PHPCMS 为例)
很多框架默认 debug 模式开启时会渲染详细错误页,极易泄露数据库配置:
立即学习“PHP免费学习笔记(深入)”;
- ThinkPHP 5.0.x:确保
APP_DEBUG = false,升级至 ≥5.1.23;检查是否残留database.php可被直接访问(如/data/database.php) - Laravel:确认
APP_DEBUG=false,且.env文件不在 Web 可访问目录下(Nginx/Apache 需禁止访问.env) - PHPCMS:禁用调试模式,更新至最新版;检查
phpcms/config/database.php是否可通过 URL 直接下载
验证与巡检要点
光改配置不够,得动手验证是否真堵住了:
- 故意触发数据库错误(如传一个不存在的表名),检查浏览器响应体、控制台、网络面板——不应出现 MySQL、PDO、SQLSTATE 等关键词
- 查看服务器错误日志,确认该错误已记录,且内容含文件路径和行号(供排查),但不含数据库密码或完整 SQL
- 用 curl 或 Postman 请求一个带非法参数的接口,响应状态码应为 500,body 应是通用提示(如 JSON 中
"message": "服务异常"),而非堆栈或 SQL 报错



















