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


Posted in PHP onMay 14, 2019

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

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

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

注册异常处理器

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

# config/web.php
'components' => [
  'errorHandler' => [
    'errorAction' => 'exception/handler'
  ]
]

异常处理器

定义相应的异常处理器,app\actions\ErrorApiAction 继承 yii\web\ErrorAction,可以拿到yii2为我们整理好的全局异常。

# controllers/ExceptionController.php
<?php

namespace app\controllers;

use yii\web\Controller;

class ExceptionController extends Controller
{
  /**
   * 为 actionHandler 挂载独立的 action
   * @return array
   */
  public function actions()
  {
    return [
      'handler' => [
        'class' => 'app\actions\ErrorApiAction',
      ]
    ];
  }
}

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

#actions/ErrorApiAction.php
<?php
/**
 * @author wangzhijian@styd.com
 * @date 2019-5-13 17:20:10
 * Api 全局错误异常处理器
 */

namespace app\actions;

use Yii;
use yii\web\ErrorAction;
use yii\web\Response;

class ErrorApiAction extends ErrorAction
{
  public function run()
  {
    // 根据异常类型设定相应的响应码
    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

<?php
/**
 * app 异常基础类
 */

namespace app\exceptions;

class HttpException extends \yii\web\HttpException
{
  public function __construct($message = null, $code = 0, \Exception $previous = null)
  {
    parent::__construct($this->statusCode, $message, $code, $previous);
  }
}

exceptions/HttpForbiddenException.php

<?php
/**
 * 400 bad request
 */

namespace app\exceptions;

class HttpBadRequestException extends HttpException
{
  public $statusCode = 400;
}

exceptions/HttpUnauthorizedException.php

<?php
/**
 * 401 unauthorized
 */

namespace app\exceptions;

class HttpUnauthorizedException extends HttpException
{
  public $statusCode = 401;
}

exceptions/HttpForbiddenException.php

<?php
/**
 * 403 forbidden
 */

namespace app\exceptions;

class HttpForbiddenException extends HttpException
{
  public $statusCode = 403;
}

exceptions/HttpNotFoundException.php

<?php
/**
 * 404 not found
 */

namespace app\exceptions;

class HttpNotFoundException extends HttpException
{
  public $statusCode = 404;
}

使用范例

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

throw new HttpBadRequestException("具体的非法描述", 4001);
throw new HttpUnauthorizedException("请认证后访问");
throw new HttpForbiddenException("无权访问");
throw new HttpNotFoundException("请求资源不存在");

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
在PHP的图形函数中显示汉字
Oct 09 PHP
PHP初学入门
Nov 19 PHP
PHP循环获取GET和POST值的代码
Apr 09 PHP
PHP中文分词 自动获取关键词介绍
Nov 13 PHP
WAMP环境中扩展oracle函数库(oci)
Jun 26 PHP
PHP内核探索之解释器的执行过程
Dec 22 PHP
PHP文件及文件夹操作之创建、删除、移动、复制
Jul 13 PHP
深入讲解PHP的对象注入(Object Injection)
Mar 01 PHP
PHP连接sftp并下载文件的方法教程
Aug 26 PHP
php实现微信企业转账功能
Oct 02 PHP
yii2 在控制器中验证请求参数的使用方法
Jun 19 PHP
php-7.3.6 编译安装过程
Feb 11 PHP
yii2的restful api路由实例详解
May 14 #PHP
php的扩展写法总结
May 14 #PHP
PHP利用pdo_odbc实现连接数据库示例【基于ThinkPHP5.1搭建的项目】
May 13 #PHP
thinkPHP框架通过Redis实现增删改查操作的方法详解
May 13 #PHP
ThinkPHP3.2框架自带分页功能实现方法示例
May 13 #PHP
PHP使用Redis实现Session共享的实现示例
May 12 #PHP
如何让PHP编码更加好看利于阅读
May 12 #PHP
You might like
用PHP生成自己的LOG文件
2006/10/09 PHP
PHP用GD库生成高质量的缩略图片
2011/03/09 PHP
PHP中的命名空间详细介绍
2015/07/02 PHP
Symfony2实现在controller中获取url的方法
2016/03/18 PHP
thinkPHP+LayUI 流加载实现功能
2019/09/27 PHP
Js获取事件对象代码
2010/08/05 Javascript
jquery getScript动态加载JS方法改进详解
2012/11/15 Javascript
JS和jQuery使用submit方法无法提交表单的原因分析及解决办法
2016/05/17 Javascript
实用又漂亮的BootstrapValidator表单验证插件
2016/05/30 Javascript
jquery中用函数来设置css样式
2016/12/22 Javascript
详解jQuery中ajax.load()方法
2017/01/25 Javascript
vue.js全局API之nextTick全面解析
2017/07/07 Javascript
vue.js根据代码运行环境选择baseurl的方法
2018/02/28 Javascript
javascript中UMD规范的代码推演
2018/08/29 Javascript
解决vue单页路由跳转后scrollTop的问题
2018/09/03 Javascript
基于vue-cli 路由 实现类似tab切换效果(vue 2.0)
2019/05/08 Javascript
在Python中使用mongoengine操作MongoDB教程
2015/04/24 Python
Python读取一个目录下所有目录和文件的方法
2016/07/15 Python
用yum安装MySQLdb模块的步骤方法
2016/12/15 Python
python深度优先搜索和广度优先搜索
2018/02/07 Python
python用opencv批量截取图像指定区域的方法
2019/01/24 Python
python接口调用已训练好的caffe模型测试分类方法
2019/08/26 Python
将python文件打包exe独立运行程序方法详解
2020/02/12 Python
如何使用Python自动生成报表并以邮件发送
2020/10/15 Python
如何基于matlab相机标定导出xml文件
2020/11/02 Python
HTML 5.1来了 9月份正式发布 更新内容预览
2016/04/26 HTML / CSS
如何写一个Java类既可以用作applet也可以用作java应用
2016/01/18 面试题
工商管理专业实习大学生自我鉴定
2013/09/19 职场文书
控制工程专业个人求职信
2013/09/25 职场文书
鞋类设计与工艺专业销售求职信
2013/11/01 职场文书
人事专员岗位职责
2013/11/20 职场文书
小学优秀班主任事迹材料
2014/05/17 职场文书
幼儿园端午节活动方案
2014/08/25 职场文书
医院护士党的群众路线教育实践活动对照检查材料思想汇报
2014/10/04 职场文书
2014年服务行业工作总结
2014/11/18 职场文书
python中opencv实现图片文本倾斜校正
2021/06/11 Python