多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
你可以通过设置`exception_tmpl`配置参数来自定义你的异常页面模板,默认的异常模板位于: ~~~ thinkphp/tpl/think_exception.tpl ~~~ 你可以在应用配置文件`app.php`中更改异常模板 ~~~ // 自定义异常页面的模板文件 'exception_tmpl' => \think\facade\App::getAppPath() . 'template/exception.tpl', ~~~ 默认的异常页面会返回`500`状态码,如果是一个`HttpException`异常则会返回HTTP的错误状态码。 ## **自定义异常处理类** 框架支持异常处理由开发者自定义类进行接管, 在`app`目录下面的`provider.php`文件中绑定异常处理类,例如: ``` <?php use app\ExceptionHandle; use app\Request; // 容器Provider定义文件 return [ 'think\Request' => Request::class, 'think\exception\Handle' => ExceptionHandle::class, ]; ``` 我们替换原有的vendor\topthink\framework\src\think\exception\Handle.php的Handle类 ~~~ // 绑定自定义异常处理handle类 'think\exception\Handle' => '\\app\\common\\exception\\Http', ~~~ >[danger] 事实上,默认安装应用后,已经帮你内置了一个公共的`app\ExceptionHandle`异常处理类(作用于index、admin、api等所有模块)它继承至默认的handle类,直接修改该类的相关方法即可完成应用的自定义异常处理机制。而无需在自定义Handle类 自定义异常处理的主要作用是根据不同的异常类型发送不同的状态码和响应输出格式。 自定义类需要继承`think\exception\Handle`并且实现`render`方法,可以参考如下代码: ~~~ <?php namespace app\common\exception; use think\exception\Handle; use think\exception\HttpException; use think\exception\ValidateException; use think\Response; use Throwable; class Http extends Handle { $httpStatus=500; public function render($request, Throwable $e): Response { // 参数验证错误 if ($e instanceof ValidateException) { return json($e->getError(), 422); } // 请求异常 if ($e instanceof HttpException && $request->isAjax()) { return response($e->getMessage(), $e->getStatusCode()); } // 其他错误交给系统处理 return parent::render($request, $e); } } ~~~ >[danger] 需要注意的是,如果自定义异常处理类没有再次调用系统`render`方法的话,配置`http_exception_template`就不再生效,具体可以参考`Handle`类内实现的功能。 ## 手动抛出和捕获异常 ThinkPHP大部分情况异常都是自动抛出和捕获的,你也可以手动使用`throw`来抛出一个异常,例如: ~~~ // 使用think自带异常类抛出异常 throw new \think\Exception('异常消息', 10006); ~~~ 手动捕获异常方式是使用`try-catch`,例如: ~~~ try { // 这里是主体代码 } catch (ValidateException $e) { // 这是进行验证异常捕获 return json($e->getError()); } catch (\Exception $e) { // 这是进行异常捕获 return json($e->getMessage()); } ~~~ >[danger] 支持使用`try-catch-finally`结构捕获异常。 ## **HTTP 异常** 可以使用`\think\exception\HttpException`类来抛出异常 框架提供了一个`abort`助手函数快速抛出一个HTTP异常: ~~~ namespace app\index\controller; class Index { public function index() { // 抛出 HTTP 异常 throw new \think\exception\HttpException(404, '异常消息'); } } ~~~ 系统提供了助手函数`abort`简化HTTP异常的处理,例如: 框架提供了一个`abort`助手函数快速抛出一个HTTP异常: ~~~ namespace app\index\controller; class Index { public function index() { // 抛出404异常 abort(404, '页面异常'); } } ~~~ 如果你的应用是API接口,那么请注意在客户端首先判断HTTP状态码是否正常,然后再进行数据处理,当遇到错误的状态码的话,应该根据状态码自行给出错误提示,或者采用下面的方法进行自定义异常处理。 **部署模式**下一旦抛出了`HttpException`异常,可以定义单独的异常页面模板,只需要在`app.php`配置文件中增加: ~~~ 'http_exception_template' => [ // 定义404错误的模板文件地址 404 => \think\facade\App::getAppPath() . '404.html', // 还可以定义其它的HTTP status 401 => \think\facade\App::getAppPath() . '401.html', ] ~~~ 模板文件支持模板引擎中的标签。 >[danger] `http_exception_template`配置仅在部署模式下面生效。 ## **为每个模块配置单独的异常处理类** 在`app/index`模块目录下面新建`provider.php`文件中绑定这个模块生效的异常处理类 ~~~ // 绑定自定义异常处理handle类 'think\exception\Handle' => '\\app\\index\\exception\\Http', ~~~ 在index模块中新建exception/Http.php ~~~ namespace app\index\exception; use think\exception\Handle; //use think\exception\HttpException; //use think\exception\ValidateException; use think\Response; use Throwable; class Http extends Handle { public function render($request, Throwable $e): Response { // 参数验证错误 if ($e instanceof ValidateException) { return json($e->getError(), 422); } // 请求异常 if ($e instanceof HttpException && $request->isAjax()) { return response($e->getMessage(), $e->getStatusCode()); } // 其他错误交给系统处理 return parent::render($request, $e); } } ~~~