thinkphp6需通过自定义app\exception\handler类接管异常处理,按ajax/http/验证等场景差异化返回json或html响应,防止敏感信息泄露;必须在config/app.php中配置exception_handle并清除配置缓存。

在ThinkPHP6项目中,当用户访问不存在的路由、数据库连接失败或控制器方法抛出未捕获异常时,系统默认会暴露调试信息或返回原始错误堆栈——必须通过自定义异常处理类接管,才能按AJAX/JSON、HTTP状态码、验证失败等场景差异化返回响应,同时防止敏感信息泄露。
创建自定义异常处理类
在 app/exception/ 目录下新建 Handler.php 文件(注意不是 ExceptionHandle.php,那是TP5旧名),文件路径必须与命名空间严格一致。
类必须继承 think\exception\Handle,且命名空间为 app\exception;类名必须是 Handler(若用其他名,config配置将失效)。
完整代码示例:
```php
namespace app\exception;
use think\exception\Handle;
use think\Response;
use think\exception\HttpException;
use think\exception\ValidateException;
use Throwable;
class Handler extends Handle
{
public function render($request, Throwable $e): Response
{
// 参数验证异常
if ($e instanceof ValidateException) {
return json(['code' => 422, 'msg' => $e->getError()], 422);
}
// HTTP异常(含404、500等)
if ($e instanceof HttpException) {
$code = $e->getStatusCode();
if ($request->isAjax()) {
return json(['code' => $code, 'msg' => $e->getMessage()], $code);
} else {
return view('error/' . $code, ['msg' => $e->getMessage()])->code($code);
}
}
// 其他未捕获异常统一返回500 JSON(生产环境)
if (!env('APP_DEBUG')) {
return json(['code' => 500, 'msg' => '服务器内部错误'], 500);
}
// 调试模式下仍走框架默认渲染(含堆栈)
return parent::render($request, $e);
}
}
```
配置异常处理类生效
打开 config/app.php,定位到 'exception_handle' 配置项。
将其值修改为:app\exception\Handler::class。
【这一步不可跳过】 若未在此处显式指定,框架将始终使用内置处理器,所有自定义逻辑均不会触发——且不报任何错误提示,而是静默回退。
修改后务必执行:php think clear:config 清除配置缓存,否则新配置不会加载。
区分场景返回不同格式
方法一:AJAX请求返回JSON,普通请求返回HTML错误页
在 render() 方法中用 $request->isAjax() 判断,不要依赖 $_SERVER 变量,该方式稳定可靠。
方法二:按异常类型分支处理
① ValidateException → 返回 422 + 错误字段信息
② RouteNotFoundException 或 ClassNotFoundException → 视为404,返回对应提示
③ PDOException 等数据库异常 → 建议在 report() 中记录日志,在 render() 中统一屏蔽细节,只返回 500 JSON
注意:TP6要求 render() 必须返回 Response 实例,不能 echo、die 或返回字符串,否则会中断响应流程。
手动抛出可被接管的业务异常
方法一:直接使用框架内置异常类
在控制器中写:throw new \think\exception\HttpException(400, '参数缺失', ['code' => 1001]);
方法二:定义自己的业务异常基类(推荐)
在 app/exception/BusinessException.php 中创建:
```php
namespace app\exception;
use think\Exception;
class BusinessException extends Exception
{
protected $httpCode = 200;
public function __construct($code = 0, $message = '', $httpCode = 200)
{
$this->httpCode = $httpCode;
parent::__construct($message, $code);
}
}
```
然后在控制器中:throw new BusinessException(1002, '用户未登录', 401);
【关键前提】 自定义异常类必须继承 think\Exception 或其子类,否则 render() 中的 instanceof 判断会失败,导致走默认兜底逻辑。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











