display_errors = off 是防止信息泄露的第一道防线,避免php错误暴露路径、配置等敏感信息;生产环境应关闭它,改用 log_errors = on 并确保 error_log 路径可写来可靠捕获错误。

display_errors = Off 是防止信息泄露的第一道防线
生产环境开启 display_errors 会让 PHP 把 Fatal error、Parse error、Warning 等原始错误直接输出到 HTTP 响应体里——这意味着用户(或攻击者)可能看到绝对路径、数据库配置片段、函数调用栈、扩展名甚至部分源码。Workerman 本身不渲染 HTML,但一旦你用它做 HTTP 服务(比如配合 WebServer 或自定义 HTTP Worker),错误照样会裸露在响应中。
Workerman 进程崩溃时 display_errors=On 反而掩盖真实原因
当 Workerman 子进程因致命错误退出(例如状态码 256),如果 display_errors = On 且运行在守护进程模式下,错误往往不会出现在终端或日志里,而是被丢进黑洞——因为 stdout/stderr 在 daemonize 后常被重定向或关闭。此时你既看不到报错,又没日志,只剩一个静默退出的 worker。
-
ini_set('display_errors', 'on')在 daemon 模式下基本无效,别依赖它查问题 - 真正有效的错误捕获靠的是
log_errors = On+error_log路径可写 - Workerman 的
Config::$debug = true输出的是框架生命周期事件(如 “worker 1 started”),不是 PHP 错误;它和display_errors是两套机制,不能互相替代
线上错误该去哪?不是浏览器,是日志文件
关掉 display_errors 不等于放弃可观测性,而是把错误导流到可控位置:
- 确保
log_errors = On,并检查error_log指向的路径(如/var/log/php_errors.log)存在且 Web 服务器用户(如www-data)有写权限 - Workerman 自身的日志(如
workerman.log)默认只记录主进程动作,PHP 运行时错误必须靠 PHP 原生日志机制捕获 - 若用 Monolog 或其他日志库,记得在
set_error_handler和set_exception_handler中统一接入,避免错误散落各处
别信“临时加 ini_set 就能调试”
在 Workerman 启动文件顶部写 ini_set('display_errors', 'on'),看似简单,实则风险高、效果差:
- 很多生产环境 php.ini 中
display_errors被设为system级别,ini_set无法覆盖 - 即使生效,错误会混在 Workerman 的 stdout 日志里(比如
start.php -d启动时),难以区分是框架日志还是业务错误 - 更稳的方式是:开发阶段用非 daemon 模式 +
error_reporting(E_ALL)+log_errors=On,错误全进文件;上线前删掉所有ini_set('display_errors')相关代码
log_errors 是否真开启、error_log 路径是否真的可写、日志轮转是否配置妥当。这些细节漏掉一个,就等于关了门却没锁窗。











