API使用面向对象特性,给予thinkPHP5 全局异常处理封装

  任何程序还是框架异常处理是难点和重点之一。今天学习thinkPHP5 框架的同时,对面向对象框架的通过AOP切面思想封装异常处理层有了初步理解,在此记录一下 。

 一、异常按照作用分为两类

1、业务异常:非代码问题,犹豫用户的输入和数据处理过程中而开发人员产生的异常,需要将异常原因和处理结果返回展示给用户,一般不需要记录日志。对系统的稳定性和流畅性没有影响,可以预测异常的产生,一般能够确定明显的原因,

2、系统异常:一般是代码或者逻辑原因产生的异常,无法预测,原因不明确,属于系统bug。这种异常不需要给展示给用户,只提示“服务异常”等提示就可以。具体异常内容和环境状况需要记录到日志,一般后续开发人员查看并排查。对系统的稳定性产生影响。

二、面向对象异常特性

1、一般语言都有异常类Exception,自定义异常都需要继承自该Exception异常类

2、一般框架都有抛出异常的类,需要重写该抛出异常的类来自定义抛出异常

3、抛出异常是按照冒泡规则向上级逐步传递异常

class BannerModel
{
    public static function getBannerById($id)
    {
        // 底层:在model类里面抛出异常
        try {
            1 / 0;
        }catch (Exception $exception) {
            throw $exception;
        }
        return 'this is banner ';
    }
}

 Model类里对按抛出一个异常,可以在调用model类的controller类二次处理异常(包括日志记录,保存现场数据等),也可以不捕获,直接在model类抛出

class BannerController
{
    function getBanner($id)
    {
        (new IdMustBePositiveInt())->goCheck();
    try{
        $banner = BannerModel::getBannerById($id);
    }catch(Exception $e){
        // 捕获model类里抛出的异常,做其他的操作或者直接抛出
        throw $;
    }
        return $banner;
    }
}

三、thinkPHP 5 封装自定义异常处理层

1、自定义BaseException类,该类继承与框架的Exception并且初始化自定义异常抛出所需要的参数。一般api接口会初始化三个参数,code代表状态码,通过http状态返回,msg作为具体异常信息抛出,err_Code是具体异常所属的系统自定义的异常代码。

class BaseException extends Exception
{
    // http状态码
    public $code = 400;

    // 错误具体信息
    public $mgs = '参数错误';

    // 自定义错误码
    public $errCode = 10000;
}

2、编写每一个具体情况的自定义异常。该异常类继承自前面定义的BaseException,并且重写三个抛出异常所需要的参数,表示当前异常的信息。下面是一个Banner不存在异常

class BannerMissException extends BaseException
{
    // http状态码
    public $code = 404;

    public $mgs = '请求的轮播图不存在';
    // 系统所定义的异常代码
    public $errCode = 40000;
}

3、重写抛出异常的函数类。将render函数重写,自定义抛出异常。将异常按照前面的分类,分成两种种类。如果一个异常是我们自定义编写的异常属于业务异常,自定义业务异常格式化以后按照api标注输出给客户端。系统异常按照格式化以后跟环境信息一起保存到系统日志,一遍排查处理。

class ExceptionHandler extends Handle
{
    private $code;
    private $msg;
    private $errCode;
    // 返回客户端当前请求的url路径


    public function render(Exception $e)
    {
        if ($e instanceof BaseException) {
            // 如果是自定义异常,需要传给客户端
            $this->code = $e->code;
            $this->msg = $e->mgs;
            $this->errCode = $e->errCode;
        }else{
            // 系统是异常
            // 开发模式下抛出默认异常页面,错误信息比较详细,方便调试
            if(config('app_debug')){
                return parent::render($e);
            }
            // 非开发模式,抛出自定义异常给客户端
            $this->code = 500;
            $this->msg = '服务器内部错误,请联系开发人员';
            $this->errCode = 999;
            // 同时将异常情况记录到日志
            $this->recordErrorLog($e);
        }
        $request = Request::instance();

        $result = [
            'msg' => $this->msg,
            'error_code' => $this->errCode,
            'request_url' => $request->url()
        ];
        return json($result, $this->code); // TODO: Change the autogenerated stub
    }

    private function recordErrorLog(Exception $e) {
        Log::init([
            'type' => 'File',
            'path' => LOG_PATH,
            'level' => ['error']
        ]);
        Log::record($e->getMessage(), 'error');
    }
}

这样就封装好了一个异常自定义异常处理框架。如果在代码中抛出的是像BannerMissException这种异常是我们自定义的异常,会抛出给客户端。其余我们没有定义过的异常一律按照系统异常抛出并记录到日志。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值