生产环境必须关闭display_errors并开启log_errors,防止敏感信息泄露且确保错误可追溯;需配置error_log路径权限、catch_workers_output及slowlog,并验证生效。

生产环境必须关闭错误显示,但不是“隐错设置”本身必要,而是防止敏感信息泄漏、避免干扰正常流程——display_errors 必须关,log_errors 必须开。
为什么不能留着 display_errors = On
PHP 默认可能开启错误输出,一旦上线还开着,Parse error、Warning: mysqli_connect(): Access denied 这类信息会直接打在页面上,攻击者能立刻看到路径、扩展名、数据库配置片段甚至部分代码逻辑。
-
display_errors = Off(php.ini 或运行时用ini_set('display_errors', '0')) - 别依赖 .htaccess 或
ini_set()覆盖:某些致命错误(如语法错)在脚本执行前就报出,ini_set()根本没机会运行 - 如果用了 opcache,改完 php.ini 后记得重启 PHP-FPM 或 Apache,否则配置不生效
error_log 日志路径和权限容易被忽略
只关显示不记日志,等于把问题藏进黑箱。线上出问题时,没有日志等于盲人摸象。
-
log_errors = On是前提,否则任何错误都不会写入日志 -
error_log = /var/log/php/error.log:路径要绝对,且确保 PHP 进程用户(如www-data或nginx)有写权限;常见坑是目录存在但父目录无写权限 - 避免写到
/tmp或 Web 可访问目录(如./logs/),防止被直接下载 - 日志级别建议保持默认
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT,太低会漏掉潜在问题
FPM 模式下还要检查 catch_workers_output
PHP-FPM 里,子进程的 stdout/stderr 默认不被捕获,意味着 echo、var_dump、未捕获异常的堆栈,可能直接丢进 FPM 的主错误日志(如 /var/log/php-fpm/www-error.log),而不是你的 error_log 文件。
立即学习“PHP免费学习笔记(深入)”;
- 确认
catch_workers_output = yes(在 www.conf 中),否则调试时会找不到输出痕迹 - 同时检查
slowlog是否启用:慢请求日志对定位性能卡点很关键,不是可选项 - FPM 的
access.log记录的是 HTTP 请求,和 PHP 错误无关,别混淆
真正麻烦的从来不是设几个 ini 项,而是改完之后没验证——用一个带语法错误的 PHP 文件触发一次 Parse error,看页面是否空白、日志是否新增条目、FPM 日志里有没有残留输出,才算闭环。











