Nginx error_log 默认不记录 PHP 脚本错误,需通过 PHP-FPM 的 catch_workers_output = yes 并配置 php_admin_value[error_log] 指向 Nginx error_log 路径,或在 PHP 中调用 error_log() 写入同一路径来实现。

nginx 的 error_log 本身不会自动记录 PHP 脚本执行错误,它只记录 Nginx 自身的运行问题(如配置加载失败、连接上游超时、权限拒绝等)。PHP-FPM 返回的 500 或其他错误响应,Nginx 默认只记为 upstream sent too big header 或 connect() failed 类提示,而非具体的 PHP 错误内容。要让 error_log 捕捉到 PHP 层面的交互报错,必须通过 PHP-FPM 主动把错误“推”给 Nginx 日志系统,或确保错误最终落进 Nginx 可读写的日志路径。
让 PHP 错误出现在 Nginx error_log 的两种可靠方式
方式一:依赖 PHP-FPM 的 catch_workers_output = yes + 标准错误重定向
这是最常用且兼容性最好的做法。PHP-FPM worker 进程的标准错误(stderr)默认被丢弃到 /dev/null。启用该选项后,worker 的 stderr 会被捕获,并由 PHP-FPM 主进程写入其配置的 error_log 文件——而这个文件,可以和 Nginx 的 error_log 设为同一路径。
- 编辑
/etc/php-fpm.d/www.conf(或对应 pool 配置),添加或取消注释:
php_admin_value[error_log] = /var/log/nginx/error.log
php_admin_flag[log_errors] = on
- 确保
/var/log/nginx/error.log对 PHP-FPM 运行用户(如www-data或nginx)有写权限 - 重启 PHP-FPM:
systemctl restart php-fpm
方式二:在 PHP 代码中显式调用 error_log() 并指定 Nginx 日志路径
适用于调试特定逻辑,或框架未触发全局错误日志时。
- 在 PHP 脚本里直接写:
- 注意:
3表示写入文件;路径必须与 Nginxerror_log配置一致,且 PHP 进程有权限写入 - 此方法不依赖
log_errors或display_errors设置,但需手动插入,不适合全量捕获
必须同步检查的 PHP 运行时配置
即使 PHP-FPM 把 stderr 推过去了,若 PHP 自身没开启错误记录,也不会产生可捕获的内容。
立即学习“PHP免费学习笔记(深入)”;
- 确认
php.ini中已启用基础错误日志:
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
error_log = /dev/null ← 此项建议设为 /dev/null 或留空,避免与 php_admin_value 冲突
- 关键点:
php_admin_value[error_log]在 php-fpm pool 配置中会强制覆盖php.ini的error_log,所以不要在 php.ini 里硬编码路径,交由 FPM 统一管理 - 运行
phpinfo()查看最终生效的error_log路径,确保它指向你期望的位置
避免常见干扰项
有些配置看似相关,实则会让错误“消失”或转向别处:
-
display_errors = On是输出到浏览器的开关,与日志无关;生产环境应始终为Off -
error_page 500 502 503 504 /50x.html;会拦截真实错误响应并返回静态页,导致原始错误不进入日志——临时调试时建议注释掉 - Nginx 的
fastcgi_intercept_errors on;会让 Nginx 自己处理 4xx/5xx 响应,可能掩盖上游错误细节;调试阶段建议设为off - 若使用宝塔等面板,注意其“PHP 错误日志”开关实际修改的是
php_admin_value[error_log],需确认路径是否指向 Nginx error_log
验证是否生效
写一个测试脚本 /var/www/html/test.php:
trigger_error("This is a test E_USER_ERROR", E_USER_ERROR);
?>
- 访问该页面,然后立即执行:
tail -f /var/log/nginx/error.log - 应看到类似内容:
[error] ... *17689 FastCGI sent in stderr: "PHP message: This is a test E_USER_ERROR" while reading response header from upstream - 若无输出,检查 PHP-FPM 用户权限、配置是否重载、SELinux/AppArmor 是否拦截写入



















