錯誤處理(Handling Errors)

2018-02-24 15:40 更新

錯誤處理

Yii 內(nèi)置了一個yii\web\ErrorHandler錯誤處理器,它使錯誤處理更方便, Yii錯誤處理器做以下工作來提升錯誤處理效果:

  • 所有非致命PHP錯誤(如,警告,提示)會轉(zhuǎn)換成可獲取異常;
  • 異常和致命的PHP錯誤會被顯示,在調(diào)試模式會顯示詳細的函數(shù)調(diào)用棧和源代碼行數(shù)。
  • 支持使用專用的?控制器操作?來顯示錯誤;
  • 支持不同的錯誤響應格式;

yii\web\ErrorHandler 錯誤處理器默認啟用, 可通過在應用的入口腳本中定義常量YII_ENABLE_ERROR_HANDLER來禁用。

使用錯誤處理器

yii\web\ErrorHandler 注冊成一個名稱為errorHandler應用組件, 可以在應用配置中配置它類似如下:

return [
    'components' => [
        'errorHandler' => [
            'maxSourceLines' => 20,
        ],
    ],
];

使用如上代碼,異常頁面最多顯示20條源代碼。

如前所述,錯誤處理器將所有非致命PHP錯誤轉(zhuǎn)換成可獲取異常,也就是說可以使用如下代碼處理PHP錯誤:

use Yii;
use yii\base\ErrorException;

try {
    10/0;
} catch (ErrorException $e) {
    Yii::warning("Division by zero.");
}

// execution continues...

如果你想顯示一個錯誤頁面告訴用戶請求是無效的或無法處理的,可簡單地拋出一個 yii\web\HttpException異常, 如 yii\web\NotFoundHttpException。錯誤處理器會正確地設置響應的HTTP狀態(tài)碼并使用合適的錯誤視圖頁面來顯示錯誤信息。

use yii\web\NotFoundHttpException;

throw new NotFoundHttpException();

自定義錯誤顯示

yii\web\ErrorHandler錯誤處理器根據(jù)常量YII_DEBUG的值來調(diào)整錯誤顯示, 當YII_DEBUG?為 true (表示在調(diào)試模式),錯誤處理器會顯示異常以及詳細的函數(shù)調(diào)用棧和源代碼行數(shù)來幫助調(diào)試, 當YII_DEBUG?為 false,只有錯誤信息會被顯示以防止應用的敏感信息泄漏。

補充: 如果異常是繼承 yii\base\UserException,不管YII_DEBUG為何值,函數(shù)調(diào)用棧信息都不會顯示, 這是因為這種錯誤會被認為是用戶產(chǎn)生的錯誤,開發(fā)人員不需要去修正。

yii\web\ErrorHandler 錯誤處理器默認使用兩個視圖顯示錯誤:

  • @yii/views/errorHandler/error.php: 顯示不包含函數(shù)調(diào)用棧信息的錯誤信息是使用, 當YII_DEBUG?為 false時,所有錯誤都使用該視圖。
  • @yii/views/errorHandler/exception.php: 顯示包含函數(shù)調(diào)用棧信息的錯誤信息時使用。

可以配置錯誤處理器的 yii\web\ErrorHandler::errorView 和 yii\web\ErrorHandler::exceptionView 屬性 使用自定義的錯誤顯示視圖。

使用錯誤操作

使用指定的錯誤操作?來自定義錯誤顯示更方便, 為此,首先配置errorHandler組件的 yii\web\ErrorHandler::errorAction 屬性,類似如下:

return [
    'components' => [
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
    ]
];

yii\web\ErrorHandler::errorAction 屬性使用路由到一個操作, 上述配置表示不用顯示函數(shù)調(diào)用棧信息的錯誤會通過執(zhí)行site/error操作來顯示。

可以創(chuàng)建site/error?操作如下所示:

namespace app\controllers;

use Yii;
use yii\web\Controller;

class SiteController extends Controller
{
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
        ];
    }
}

上述代碼定義error?操作使用yii\web\ErrorAction 類,該類渲染名為error視圖來顯示錯誤。

除了使用yii\web\ErrorAction, 可定義error?操作使用類似如下的操作方法:

public function actionError()
{
    $exception = Yii::$app->errorHandler->exception;
    if ($exception !== null) {
        return $this->render('error', ['exception' => $exception]);
    }
}

現(xiàn)在應創(chuàng)建一個視圖文件為views/site/error.php,在該視圖文件中,如果錯誤操作定義為yii\web\ErrorAction, 可以訪問該操作中定義的如下變量:

  • name: 錯誤名稱
  • message: 錯誤信息
  • exception: 更多詳細信息的異常對象,如HTTP 狀態(tài)碼,錯誤碼,錯誤調(diào)用棧等。

補充: 如果你使用?基礎應用模板?或?高級應用模板, 錯誤操作和錯誤視圖已經(jīng)定義好了。

自定義錯誤格式

錯誤處理器根據(jù)響應設置的格式來顯示錯誤, 如果yii\web\Response::format 響應格式為html, 會使用錯誤或異常視圖來顯示錯誤信息,如上一小節(jié)所述。 對于其他的響應格式,錯誤處理器會錯誤信息作為數(shù)組賦值給yii\web\Response::data屬性,然后轉(zhuǎn)換到對應的格式, 例如,如果響應格式為json,可以看到如下響應信息:

HTTP/1.1 404 Not Found
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8

{
    "name": "Not Found Exception",
    "message": "The requested resource was not found.",
    "code": 0,
    "status": 404
}

可在應用配置中響應response組件的beforeSend事件來自定義錯誤響應格式。

return [
    // ...
    'components' => [
        'response' => [
            'class' => 'yii\web\Response',
            'on beforeSend' => function ($event) {
                $response = $event->sender;
                if ($response->data !== null) {
                    $response->data = [
                        'success' => $response->isSuccessful,
                        'data' => $response->data,
                    ];
                    $response->statusCode = 200;
                }
            },
        ],
    ],
];

上述代碼會重新格式化錯誤響應,類似如下:

HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8

{
    "success": false,
    "data": {
        "name": "Not Found Exception",
        "message": "The requested resource was not found.",
        "code": 0,
        "status": 404
    }
}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號