webman全局异常捕获必须依赖set_error_handler、set_exception_handler和register_shutdown_function三者协同,因try-catch无法捕获e_error、e_warning等原生错误;config/exception.php配置handler、error_handler、shutdown_handler三类处理器,缺一不可。

Webman 的全局异常捕获不能靠 try-catch 覆盖业务代码,必须用框架层的错误处理器接管 PHP 的 E_ERROR、E_WARNING 等原生错误,再配合 set_exception_handler 拦截未捕获异常——否则除零、未定义变量这类致命错误直接 500,根本进不到你的逻辑里。
为什么 try-catch 在 Webman 里基本无效
PHP 的 try-catch 只能捕获 Exception 和继承它的对象,但像 $i = 5 / 0 触发的是 E_WARNING(错误),不是异常;undefined variable 是 E_NOTICE;call to undefined function 是 E_ERROR。这些默认无法被 try-catch 捕获。
- Webman 启动时已通过
error_reporting(0)关闭了错误输出,但错误本身仍会中断执行 - 你写的
try-catch只在当前作用域生效,控制器方法外的底层错误(如数据库连接失败、扩展缺失)完全绕过它 - 真正起作用的是
set_error_handler()+set_exception_handler()的组合接管
config/exception.php 是核心入口点
Webman 的异常处理逻辑由 config/exception.php 文件驱动,它返回一个数组,定义了三类处理器:
-
handler:处理所有未被捕获的Exception(比如throw new RuntimeException()) -
error_handler:处理E_ERROR、E_WARNING、E_NOTICE等 PHP 错误 -
shutdown_handler:兜底函数,在脚本终止前执行,用于捕获E_ERROR级别错误(因error_handler有时不触发)
示例配置片段:
return [
'handler' => \support\exception\Handler::class,
'error_handler' => [\support\exception\Handler::class, 'handleError'],
'shutdown_handler' => [\support\exception\Handler::class, 'handleShutdown']
];
注意:\support\exception\Handler 是 Webman 自带的默认处理器,它内部已做了 JSON 化和 debug 控制——config/app.php 中的 'debug' => false 会让敏感堆栈信息不返回给前端。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
自定义异常处理器要同时覆盖两类错误
如果你写自己的处理器类(比如 app/exception/CustomExceptionHandler.php),必须实现两个静态方法:
-
handleException(\Throwable $e):处理Exception和Error(PHP 7+ 中Error也继承Throwable) -
handleError($errno, $errstr, $errfile, $errline):处理传统 PHP 错误,需手动转成异常或直接响应
关键点:
- 不要在
handleError里直接echo或die,要用Response::json()返回结构化数据 - 对
E_WARNING这类非致命错误,可选择忽略(return false让系统继续处理)或转为异常抛出 - 所有响应必须调用
response()->json([...]),且状态码设为400或500,避免返回 200 状态码的错误体
路由不存在时的 404 也要统一格式
Webman 默认对未匹配路由返回原始 HTML,需额外配置才能 JSON 化。修改 config/route.php 中的 not_found 配置项:
'not_found' => function ($request) {
return response()->json([
'code' => 404,
'msg' => '接口不存在',
'data' => null
], 404);
},
注意:not_found 是独立于异常处理器的机制,它只在路由层触发,不经过 exception.php;如果用了插件(如 webman-admin),可能已被插件重写,此时优先看插件文档中的 /plugin/admin/config/route.php。
最易被忽略的是 shutdown_handler 的兜底能力——它能在脚本崩溃的最后一刻抢救一次响应,但无法恢复执行,只能保证返回 JSON;而 error_handler 对某些严重错误(如内存耗尽)也可能失效。所以真正健壮的处理,是三者缺一不可,且都要做 debug 开关判断。










