yii2 开发api接口时优雅的处理全局异常的方法

摘要:这篇文章主要介绍了yii2 开发api接口时优雅的处理全局异常的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习 2019-05-15 23:20:47

前言:个人觉得,学习或温习一套Web框架,在快速阅读一遍文档后,应从路由,控制器,请求/响应对象,数据模型(Logic,Dao,Entity),全局异常处理几个方面下手,这几项了解后,框架上手就游刃有余了。然后我比较喜欢在开工前整理好框架的全局异常处理,方便写api时错误的统一响应。

在api接口的开发过程中,我们需要对用户数据进行严格的校验,防止非法输入对服务产生安全问题,在开发过程中,我比较喜欢即时的以抛出异常的方式中断请求的处理,并以全局异常处理器格式化处理后统一返回给客户端。

今天就把yii2自带的全局异常处理器改写至对api友好(yii2的yiiwebHttpException默认对 web 请求友好,都是以text/html的方式返回错误描述,对api不友好,api当然是json)。

注册异常处理器

yii2也是以controller/action的方式定义一个异常处理器的,我们可以在components=>errorHandler中自定义。


1
2
3
4
5
6
# config/web.php
'components'=> [
  'errorHandler'=> [
    'errorAction'=>'exception/handler'
  ]
]

异常处理器

定义相应的异常处理器,appactionsErrorApiAction继承yiiwebErrorAction,可以拿到yii2为我们整理好的全局异常。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# controllers/ExceptionController.php
<?php
 
namespaceappcontrollers;
 
useyiiwebController;
 
classExceptionControllerextendsController
{
  /**
   * 为 actionHandler 挂载独立的 action
   * @return array
   */
  publicfunctionactions()
  {
    return[
      'handler'=> [
        'class'=>'appactionsErrorApiAction',
      ]
    ];
  }
}

对api友好的错误异常处理器,这里我也只是简单的把响应格式改了一下,异常的上下文还是用yii2自带的处理的。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#actions/ErrorApiAction.php
<?php
/**
 * @author wangzhijian@styd.com
 * @date 2019-5-13 17:20:10
 * Api 全局错误异常处理器
 */
 
namespaceappactions;
 
useYii;
useyiiwebErrorAction;
useyiiwebResponse;
 
classErrorApiActionextendsErrorAction
{
  publicfunctionrun()
  {
    // 根据异常类型设定相应的响应码
    Yii::$app->getResponse()->setStatusCodeByException($this->exception);
    // json 格式返回
    Yii::$app->getResponse()->format = Response::FORMAT_JSON;
    // 返回的内容数据
    return[
      'msg'=>$this->exception->getMessage(),
      'err'=>$this->exception->getCode()
    ];
  }
}

异常实体

主要是简单的把状态码的传递封装一下,用更容易理解的类名来代理传递。
exceptions/HttpException.php


1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
/**
 * app 异常基础类
 */
 
namespaceappexceptions;
 
classHttpExceptionextendsyiiwebHttpException
{
  publicfunction__construct($message= null,$code= 0, Exception$previous= null)
  {
    parent::__construct($this->statusCode,$message,$code,$previous);
  }
}

exceptions/HttpForbiddenException.php


1
2
3
4
5
6
7
8
9
10
11
<?php
/**
 * 400 bad request
 */
 
namespaceappexceptions;
 
classHttpBadRequestExceptionextendsHttpException
{
  public$statusCode= 400;
}

exceptions/HttpUnauthorizedException.php


1
2
3
4
5
6
7
8
9
10
11
<?php
/**
 * 401 unauthorized
 */
 
namespaceappexceptions;
 
classHttpUnauthorizedExceptionextendsHttpException
{
  public$statusCode= 401;
}

exceptions/HttpForbiddenException.php


1
2
3
4
5
6
7
8
9
10
11
<?php
/**
 * 403 forbidden
 */
 
namespaceappexceptions;
 
classHttpForbiddenExceptionextendsHttpException
{
  public$statusCode= 403;
}

exceptions/HttpNotFoundException.php


1
2
3
4
5
6
7
8
9
10
11
<?php
/**
 * 404 not found
 */
 
namespaceappexceptions;
 
classHttpNotFoundExceptionextendsHttpException
{
  public$statusCode= 404;
}

使用范例

在一些service logic model中根据需要即时抛出异常即可,上层控制器拿到的永远都是正常的返回数据,绝对的2xx响应簇


1
2
3
4
thrownewHttpBadRequestException("具体的非法描述", 4001);
thrownewHttpUnauthorizedException("请认证后访问");
thrownewHttpForbiddenException("无权访问");
thrownewHttpNotFoundException("请求资源不存在");

以上就是本文的全部内容,希望对大家的学习有所帮助。

上一篇:没有了

下一篇:Laravel推荐使用的十个辅助函数

24小时热闻

鄂ICP备13002501号-1