前言:我的以爲,學習或溫習一套Web
框架,在快速閱讀一遍文檔後,應從路由,控制器,請求/響應對象,數據模型(Logic,Dao,Entity),全局異常處理
幾個方面下手,這幾項瞭解後,框架上手就遊刃有餘了。而後我比較喜歡在開工前整理好框架的全局異常處理,方便寫 api
時錯誤的統一響應。php
在api
接口的開發過程當中,咱們須要對用戶數據進行嚴格的校驗,防止非法輸入對服務產生安全問題,在開發過程當中,我比較喜歡即時的以拋出異常
的方式中斷請求的處理,並以全局異常處理器
格式化處理後統一返回給客戶端。html
今天就把 yii2
自帶的全局異常處理器改寫至對 api
友好(yii2
的 yii\web\HttpException
默認對 web 請求友好,都是以text/html
的方式返回錯誤描述,對api
不友好,api
固然是json
)。web
yii2
也是以 controller/action
的方式定義一個異常處理器的,咱們能夠在 components=>errorHandler
中自定義。json
# config/web.php 'components' => [ 'errorHandler' => [ 'errorAction' => 'exception/handler' ] ]
定義相應的異常處理器,app\actions\ErrorApiAction
繼承 yii\web\ErrorAction
,能夠拿到yii2
爲咱們整理好的全局異常。api
# 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
yii2
<?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
app
<?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
yii
<?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("請求資源不存在");
2019-5-16 今天發現 yii2 自帶了一些 http 的異常類,是我沒仔細看源碼....
yii\web\BadRequestHttpException yii\web\ConflictHttpException yii\web\ForbiddenHttpException yii\web\GoneHttpException yii\web\MethodNotAllowedHttpException yii\web\NotAcceptableHttpException yii\web\NotFoundHttpException yii\web\RangeNotSatisfiableHttpException yii\web\ServerErrorHttpException yii\web\TooManyRequestsHttpException yii\web\UnauthorizedHttpException yii\web\UnprocessableEntityHttpException yii\web\UnsupportedMediaTypeHttpException