hyperf 页面显示错误需满足三前提:启用调试模式并强制html错误页、关闭php输出缓冲确保flush生效、开启php错误报告且不被拦截;需确认异常处理器返回html响应,避免反向代理或中间件干扰。

Hyperf 默认不直接在页面显示错误,即使开启调试模式,也需要明确配置和触发条件。要让报错信息直接渲染到浏览器页面上,关键不是简单设 --debug,而是确保 异常处理器能生成 HTML 响应、错误未被静默捕获、且 PHP 错误报告级别和 Swoole 输出控制配合得当。
开启页面级错误显示需满足三个前提
-
启用调试模式并强制使用 HTML 错误页
Hyperf 的--debug参数只影响日志和部分开发行为(如禁用缓存、暴露编译错误),它本身不会自动把异常转成 HTML 页面返回。真正决定响应格式的是异常处理器的实现。
确保你用的是框架内置的Hyperf\ExceptionHandler\ErrorHandler(默认已注册),且该 handler 在config/autoload/exceptions.php中被正确挂载到对应 server(如'http' => [...])。
若自定义了AppExceptionHandler,必须显式返回 HTML 响应体,例如:return $response->withStatus(500) ->withHeader('Content-Type', 'text/html; charset=utf-8') ->withBody(new SwooleStream('<h1>Dev Error: ' . $throwable->getMessage() . '</h1>')); -
关闭 PHP 输出缓冲并确保 flush 生效
Swoole 下 PHP 的ob_*缓冲机制仍起作用。若错误发生在输出已开始后(比如中间件或控制器中),可能因缓冲未刷新而看不到内容。
可在入口或全局中间件中临时加:if (ob_get_level() > 0) ob_end_clean();
或在错误处理逻辑末尾手动刷新:
flush();
-
确保 PHP 错误报告开启且不被拦截
检查php.ini中:display_errors = On error_reporting = E_ALL log_errors = Off // 避免日志覆盖页面输出
注意:CLI 和 FPM 的
php.ini可能不同,运行php --ini和php-fpm -i | grep "Loaded Configuration File"分别确认。
快速验证是否生效的方法
执行启动命令时带上 --debug 并访问一个明显会报错的路由,例如:
#[GetMapping('/trigger-error')]
public function triggerError()
{
throw new \Exception('This should show in browser');
}
如果看到纯文本错误(如 Fatal error: Uncaught Exception...),说明 PHP 层错误已透出;如果看到 JSON 或空白,说明被某层异常处理器吞掉了,或响应头是 application/json。
常见干扰项排查
Nginx/Apache 反向代理拦截了 5xx 响应
某些 Web 服务器会把后端返回的 500 响应替换成自己的错误页。可先用curl -v http://localhost:9501/trigger-error直连 Swoole 端口验证原始响应。自定义中间件提前终止了响应
比如权限中间件里写了return response()->json(...)而没抛异常,后续异常处理器根本不会触发。确保真正“抛出”异常,而非仅返回响应。View 引擎错误被静默忽略
如 Twig 模板语法错误,默认可能只返回空响应。此时需在config/autoload/view.php中临时设'cache' => false,并确保mbstring扩展已启用(否则 UTF-8 解析失败也不报)。
不复杂但容易忽略。











