一文讲解thinkphp5中是如何自定义全局异常

发布时间 - 2021-11-02 00:00:00    点击率:

下面thinkphp框架教程栏目将给大家讲解thinkphp5中是如何自定义全局异常,希望对需要的朋友有所帮助!

为了针对书写 api 时,对各种错误返回不通的 json ,直接使用 TP5 自带的提示错误页面,对于客户端而言,明显没有任何的作用,所以需要自己来自定义全局异常。

1.创建一个全局异常的类(用于传错误信息,状态码等)

use think\Exception;
class BaseException extends Exception {
    /** HTTP 状态码
     * @var string
     */
    public $code;
    
    /** 自定义错误码
     * @var string
     */
    public $errorCode;
    
    /** 错误信息
     * @var string
     */
    public $msg;
    
    public function __construct($params=[])
    {
        if (! $params) {
            return ;
        }
        
        // 如果传了 code
        if ($array_key_exists('code', $code) {
            $this->code = $code;
        }
        
        // 如果传了 errorCode
        if (array_key_exists('errorCode', $params)) {
            $this->errorCode = $params['errorCode'];
        }
        // 如果传了 msg
        if (array_key_exists('msg', $params)) {
            $this->msg = $params['msg'];
        }
    }
}

这样就可以给以传不通的状态码,错误信息和自定义错误码。

2. 创建一个错误处理类

错误处理类,继承于TP5自带的错误处理类,重写该 render 方法,就可以自定义错误。

use Exception;
use think\exception\Handle;
use think\Request;
class ExceptionHandle extends Handle 
{
    /** 状态码
     * @var
     */
    private $code;
    /** 自定义错误码
     * @var
     */
    private $errorCode;
    /** 错误信息
     * @var
     */
    private $msg;
    
    /** 重写 Handle 方法里的Render
     * @param Exception $e
     * @return \think\response\Json
     */
            // 注意这里是基类 Exception
    public function render(Exception $e) 
    {
        if ($e instanceof BaseException) {
            //如果是自定义异常,则控制http状态码,不需要记录日志
            //因为这些通常是因为客户端传递参数错误或者是用户请求造成的异常
            //不应当记录日志
            $this->msg = $e->msg;
            $this->code = $e->code;
            $this->errorCode = $e->errorCode;
        } else {
            // 如果是服务器未处理的异常,将http状态码设置为500,并记录日志
            if (config('app_debug')) {
                // 调试状态下需要显示TP默认的异常页面,因为TP的默认页面
                // 很容易看出问题
                return parent::render($e);
            }
            $this->code = 500;
            $this->msg = '服务器内部错误,不想告诉你';
            $this->errorCode = 999;
            $this->recordErrorLog($e);
        }
        $request = Request::instance();
        $result = [
            'msg' => $this->msg,
            'errorCode' => $this->errorCode,
            'request_url' => $request->url()
        ];
        return json($result, $this->code);
    }
    
    /** 错误日志处理
     *  这里把config里日志配置的type改为test
     * @param Exception $e
     */
    private function recordErrorLog(Exception $e)
    {
        // 开启日志
        Log::init([
            'type'  =>  'File',
            'path'  =>  LOG_PATH,
            'level' => ['error']
        ]);
        
        // 日志记录方法
        Log::record($e->getMessage(),'error');
    }
    
}

3.修改配置config

// 异常处理handle类 留空使用 \think\exception\Handle
    'exception_handle'       => 'app\lib\exception\ExceptionHandle',
    
// 关闭日志    
'log'                    => [
        // 日志记录方式,内置 file socket 支持扩展
        // 关闭自动记录日志,请将type设置为test
        'type'  => 'test',
        // 日志保存目录
        'path'  => __DIR__.'/../log/',
        // 日志记录级别
        'level' => ['sql'],
    ],

4.使用错误类的方法

// 这里随便创建一个userControlelr
class UserController extends Controller {
    use app\api\model\User;
    
    /**
    * 根据 id 获取某个用户
    */
    public function getUser($id)
    {
        $user = User::get($id);
        
        // 如果 $user 为空 抛出自定义的错误,下面有...
        if(! $user) {
            throw UserMissException();
        }
        
        return json($user);
    }
}

自定义的错误子类

// 上面第一节,写的 Base 错误类派上用场了。 
class UserMissException extends BaseException
{
    /** HTTP 状态码
     * @var string
     */
    public $code = '404';
    /** 自定义错误码
     * @var string
     */
    public $errorCode = '40000';
    /** 错误信息
     * @var string
     */
    public $msg = '请求的用户不存在';
}

请求这个 getUser 方法,报错~  就会显示

{
    "msg": "请求的用户不存在",
    "errorCode": "40000",
    "request_url": "/api/v1/user/10"
}

其他的错误类型,也就可以继续创建异常子类,定义这些错误属性。

5.总结

不光是在TP5的框架,包括laravel框架,也是可以自己重新写异常类Exception的render方法,来达到自己想要的错误返回数据或者是页面模版。


# laravel  # json  # thinkphp  # 子类  # 继承  # 自定义  # 错误信息  # 传了  # 创建一个  # 错误码  # 不存在  # 或者是  # 重写  # 自带 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】  Android自定义控件实现温度旋转按钮效果  如何快速搭建个人网站并优化SEO?  如何快速生成高效建站系统源代码?  Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南  如何在橙子建站中快速调整背景颜色?  零基础网站服务器架设实战:轻量应用与域名解析配置指南  如何在自有机房高效搭建专业网站?  html5的keygen标签为什么废弃_替代方案说明【解答】  如何破解联通资金短缺导致的基站建设难题?  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法  Laravel如何优化应用性能?(缓存和优化命令)  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  Linux系统运维自动化项目教程_Ansible批量管理实战  Laravel Seeder填充数据教程_Laravel模型工厂Factory使用  Android实现代码画虚线边框背景效果  JavaScript如何操作视频_媒体API怎么控制播放  Android滚轮选择时间控件使用详解  作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】  javascript事件捕获机制【深入分析IE和DOM中的事件模型】  如何用PHP快速搭建高效网站?分步指南  如何用景安虚拟主机手机版绑定域名建站?  Internet Explorer官网直接进入 IE浏览器在线体验版网址  怎么用AI帮你设计一套个性化的手机App图标?  大型企业网站制作流程,做网站需要注册公司吗?  Laravel如何从数据库删除数据_Laravel destroy和delete方法区别  如何快速完成中国万网建站详细流程?  Python高阶函数应用_函数作为参数说明【指导】  PHP正则匹配日期和时间(时间戳转换)的实例代码  Laravel Blade模板引擎语法_Laravel Blade布局继承用法  Python结构化数据采集_字段抽取解析【教程】  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全  如何快速搭建FTP站点实现文件共享?  Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控  Laravel如何使用模型观察者?(Observer代码示例)  Laravel如何自定义分页视图?(Pagination示例)  html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】  如何在Tomcat中配置并部署网站项目?  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  Java垃圾回收器的方法和原理总结  jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】  Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】  Android使用GridView实现日历的简单功能  Laravel distinct去重查询_Laravel Eloquent去重方法  Laravel如何生成URL和重定向?(路由助手函数)  如何在阿里云虚拟主机上快速搭建个人网站?  如何在IIS中新建站点并配置端口与物理路径?  Laravel如何使用Passport实现OAuth2?(完整配置步骤)