700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > ThinkPHP6项目基操(13.实战部分 项目中的自定义异常处理总结 错误页面API错误)

ThinkPHP6项目基操(13.实战部分 项目中的自定义异常处理总结 错误页面API错误)

时间:2022-11-10 13:26:29

相关推荐

ThinkPHP6项目基操(13.实战部分 项目中的自定义异常处理总结 错误页面API错误)

项目中的自定义异常处理总结 错误页面&API错误

前言一、异常分类1. 控制器找不到2. 方法找不到3. 请求资源不存在4. 系统內部异常、HTTP异常等二、异常处理1. 前置处理2. 异常处理详细代码(1) 控制器找不到(2) 方法找不到(3) 请求资源不存在及系统错误异常三、异常检测

前言

一般项目中路由分为返回模板引擎页面和返回api接口json数据,两种方式异常需要返回不同的内容,如果是模板引擎页面遇到异常需要返回错误页面,如果是api接口遇到异常需要返回json数据。

开发模式和上线模式应该返回不同的内容,开发模式应该尽可能返回具体的错误信息,上线模式则不能返回具体的错误信息,一般显示“服务器错误,请稍后重试”类似友好的提示,而不是显示一堆报错代码(既不友好又不安全)。

如果有更好的方法,欢迎提出意见。

一、异常分类

1. 控制器找不到

在访问路由时,若控制器不对,需要使用空控制器拦截报错。

2. 方法找不到

方法找不到可以修改app目录下的BaseController控制器重写__call方法。

3. 请求资源不存在

自定义拦截报错信息,可以使用Provider自定义错误处理类,重写render方法,根据不同的错误返回不同的数据。

4. 系统內部异常、HTTP异常等

同第3点。

二、异常处理

1. 前置处理

(1).env文件定义APP_DEBUG区分开发模式和线上模式,true表示开发模式,false表示线上模式:

APP_DEBUG = true

(2) 在app/common.php文件定义api返回的数据格式:

function show($status, $message = 'error', $data = [], $httpStatus = 200){$result = ["status" => $status,"message" => $message,"result" => $data];return json($result, $httpStatus);}

(3) 在当前应用下新建一个provider.php,并指定自定义异常处理类:

<?php// 容器Provider定义文件return ['think\exception\Handle' => 'app\\admin\\exception\\Http',];

(4) 定义状态码配置,可以在config文件夹下新建status.php添加相应的状态码配置:

<?phpreturn ["success" => 1,"error" => 0,"http_status" => ["not_found" => 404,"validate_error" => 422,"internal_error" => 500]];

(5) 准备错误页面(404,500等)

2. 异常处理详细代码

(1) 控制器找不到

app/controller目录新建Error类(文件名固定为Error):

这里需要注意的是,多应用的控制器应该定义在应用文件夹里,这里定义在app目录是为了作用于app下全部应用。

<?phpnamespace app\controller;class Error{public function __call($name, $arguments){if(request()->isAjax()){return show(config("status.error"), env('app_debug') ? "控制器{$name}找不到" : '当前请求资源不存在,请稍后再试', [], config("status.http_status.not_found"));}else{return view(root_path() . 'public/error/admin/404.html', ['e' => env('app_debug') ? "控制器{$name}找不到" : '当前请求资源不存在,请稍后再试'], config("status.http_status.not_found"));}}}

(2) 方法找不到

app/BaseController.php控制器添加__call方法:

public function __call($name, $arguments){if(request()->isAjax()){return show(config("status.error"), env('app_debug') ? "找不到{$name}方法" : '当前请求资源不存在,请稍后再试', [], config("status.http_status.not_found"));}else{return view(root_path() . 'public/error/admin/404.html', ['e' => env('app_debug') ? "{$name}方法找不到" : '当前请求资源不存在,请稍后再试'], config("status.http_status.not_found"));}}

(3) 请求资源不存在及系统错误异常

app\\admin\\exception\\Http

<?phpnamespace app\admin\exception;use ErrorException;use Exception;use InvalidArgumentException;use ParseError;use PDOException;use think\exception\ClassNotFoundException;use think\exception\Handle;use think\exception\HttpException;use think\exception\RouteNotFoundException;use think\Response;use Throwable;use TypeError;class Http extends Handle{/*** Render an exception into an HTTP response.** @access public* @param \think\Request $request* @param Throwable $e* @return Response*/public function render($request, Throwable $e): Response{$returnCode = config("status.error");$returnMessage = "系统异常,请稍后再试";$returnData = [];$httpStatus = 500;if($e instanceof BusinessException){// 自定义添加的业务异常$returnMessage = $e->getMessage();$httpStatus = config("status.http_status.business_error");}else if($e instanceof ValidateException){$returnMessage = $e->getError();$httpStatus = config("status.http_status.validate_error");}else if (($e instanceof ClassNotFoundException || $e instanceof RouteNotFoundException) || ($e instanceof HttpException && $e->getStatusCode() == 404)) {$returnMessage = env('app_debug') ? $e->getMessage() : '当前请求资源不存在,请稍后再试';$httpStatus = config("status.http_status.not_found");}else if ($e instanceof Exception || $e instanceof PDOException || $e instanceof InvalidArgumentException || $e instanceof ErrorException || $e instanceof ParseError || $e instanceof TypeError || ($e instanceof HttpException && $e->getStatusCode() == 500)) {$returnMessage = env('app_debug') ? $e->getMessage() : '系统异常,请稍后再试';$httpStatus = config("status.http_status.internal_error");}if(request()->isAjax()){return show($returnCode, $returnMessage, $returnData, $httpStatus);}else{if($httpStatus == config("status.http_status.not_found")){$errorUrl = 'public/error/admin/404.html';}else{$errorUrl = 'public/error/admin/error.html';}return view(root_path() . $errorUrl, ['e'=>$returnMessage], $httpStatus);}}}

以上代码中返回的错误信息e,需要在错误页面(404,error)显示:

<p class="error-message">{$e ?? ''}</p>

三、异常检测

异常检测分浏览器页面访问异常api接口返回异常,还需要检查开发模式线上模式

控制器不存在方法不存在主动抛出异常系统抛出异常

Tips:api接口可以使用Postman工具模拟,添加Headers

Content-Typeapplication/x-www-form-urlencoded

X-Requested-Withxmlhttprequest

(博主比较懒就不贴截图了,但是都测试过,同志们自己试一下,算了还是贴一张吧)

⭐️重磅推荐:免费商用电商系统

😏想白嫖整个电商系统用来商用?

🤑想有自己的商城实现财富自由?

🤓想学习最佳实践提升自己技术?

快来进入🚀传送门🚀,开源免费、完整示例带你快速入门,轻松二开,走上人生巅峰!👨‍🎓

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。