thinkphp6异常页面自定义需按请求类型分两套逻辑:页面请求走html模板,api请求返回json;精准识别api请求推荐组合判断url前缀、中间件标记或请求属性;重写handler.php的render()方法,区分处理各类异常并设置正确响应头与状态码。

ThinkPHP6 的异常页面自定义,核心在于区分请求类型、控制响应格式、隐藏敏感信息,并保持前后端行为一致。不是简单换模板,而是要按「页面请求」和「API 请求」走两套逻辑。
精准识别 API 请求,避免 isAjax() 失效
仅靠 $request->isAjax() 判断不可靠,尤其在代理、跨域或 CLI 测试场景下容易误判。推荐组合方式:
- 检查 URL 前缀:
str_starts_with($request->url(), '/api/')或str_starts_with($request->url(), '/v1/') - 利用路由中间件标记:若 API 路由统一绑定了
api中间件,可用$request->hasMiddleware('api') - 在全局中间件中提前设属性:
$request->withAttr('is_api', true),后续直接读取$request->attr('is_api')
重写 Handler.php 的 render() 方法
在 app/common/exception/Handler.php 中修改 render(),实现分路径响应:
- 非 API 请求:直接
return parent::render($request, $e),走默认 HTML 异常页流程 - API 请求:用
response()->json()构造标准结构,例如:['code' => 500, 'msg' => $e->getMessage(), 'data' => []]
必须显式设置头:->header('Content-Type', 'application/json') - 禁用
json()辅助函数——异常上下文中可能因前置输出导致失败;response()->json()更稳定
适配各类异常类型
不同异常需单独处理,确保返回语义清晰:
-
业务异常(如
BusinessException):自定义类应含$errorCode属性,render()中用$e instanceof BusinessException判断,取$e->errorCode而非$e->getCode() -
验证异常(
ValidateException):捕获后返回422状态码,'msg' => $e->getError() -
路由异常(
RouteNotFoundException):映射为404,HttpException按实际状态码(如401、403)返回对应业务码
配置自定义 HTML 异常模板(仅限页面请求)
对非 API 请求,可通过配置指定错误页模板:
- 在
config/app.php中设置:'exception_tmpl' => app()->getRootPath() . 'view/error/exception.html' - 模板中可使用系统变量,如
{$e->getMessage()}、{$e->getFile()}、{$e->getLine()}(开发环境建议保留,生产环境应屏蔽文件路径等敏感信息) - 生产环境建议关闭调试模式:
APP_DEBUG = false,并返回简洁友好提示,不暴露堆栈
不复杂但容易忽略。关键就是识别准、分得清、设得对。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











