核心是切断错误向浏览器输出而确保安全记录:必须设display_errors=Off、log_errors=On并指定安全日志路径;catch中禁用echo异常详情,只记录日志并返回通用提示;还需关闭expose_php、禁用phpinfo()及Xdebug强制显示。

必须关掉 display_errors
这是最直接的一道防线。生产环境务必设为 Off:
- 修改 php.ini,找到
display_errors = On改成display_errors = Off - 重启 Web 服务(Apache/Nginx + PHP-FPM),否则不生效
- 别依赖
ini_set('display_errors', '0')—— 它可能被更高优先级配置覆盖,且容易遗漏 - 检查 .htaccess(Apache)或 fastcgi_param(Nginx)是否意外开启了
php_flag display_errors on
错误要进日志,而不是进页面
关显示不等于关记录。得让错误安静地写进日志:
- 确保
log_errors = On(php.ini 中) - 指定安全路径:
error_log = /var/log/php/error.log,并确认 Web 进程对该路径有写权限 - 避免把日志放在 Web 可访问目录下(如 public/ 或 www/ 下),防止被直接下载
- 验证:写个测试脚本
<?php trigger_error('test', E_USER_WARNING); ?>,访问后看页面是否空白、日志文件是否有新增内容
代码里别手动暴露异常细节
哪怕 display_errors 关了,手写的 catch 仍可能泄密:
- 禁止在
catch块中用echo $e->getMessage()或var_dump($e) - 正确做法:只调用
error_log($e->__toString(), 4)记录完整异常,前端返回统一提示,如“操作失败,请稍后重试” - 别在自定义错误处理器里打印
$_SERVER或$_REQUEST,它们包含请求路径、参数、头信息等敏感数据 - 禁用
debug_print_backtrace()等调试函数上线使用
顺手清理其他泄露渠道
错误信息常混在其它地方一起出来:
立即学习“PHP免费学习笔记(深入)”;
- 关掉
expose_php = Off(php.ini),消除响应头里的X-Powered-By: PHP/x.x.x - 禁用
phpinfo():在 php.ini 的disable_functions加上它,并删掉所有phpinfo.php类测试文件 - ThinkPHP 用户注意:
APP_DEBUG = false不够,还要确认show_error_msg = false和trace = ['status' => false] - 检查 Xdebug 是否启用
xdebug.force_display_errors = 1—— 它会绕过 display_errors 设置



















