錯(cuò)誤處理(Handling Errors)

2018-02-24 15:40 更新

錯(cuò)誤處理

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

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

yii\web\ErrorHandler 錯(cuò)誤處理器默認(rèn)啟用, 可通過(guò)在應(yīng)用的入口腳本中定義常量YII_ENABLE_ERROR_HANDLER來(lái)禁用。

使用錯(cuò)誤處理器

yii\web\ErrorHandler 注冊(cè)成一個(gè)名稱為errorHandler應(yīng)用組件, 可以在應(yīng)用配置中配置它類似如下:

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

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

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

use Yii;
use yii\base\ErrorException;

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

// execution continues...

如果你想顯示一個(gè)錯(cuò)誤頁(yè)面告訴用戶請(qǐng)求是無(wú)效的或無(wú)法處理的,可簡(jiǎn)單地拋出一個(gè) yii\web\HttpException異常, 如 yii\web\NotFoundHttpException。錯(cuò)誤處理器會(huì)正確地設(shè)置響應(yīng)的HTTP狀態(tài)碼并使用合適的錯(cuò)誤視圖頁(yè)面來(lái)顯示錯(cuò)誤信息。

use yii\web\NotFoundHttpException;

throw new NotFoundHttpException();

自定義錯(cuò)誤顯示

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

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

yii\web\ErrorHandler 錯(cuò)誤處理器默認(rèn)使用兩個(gè)視圖顯示錯(cuò)誤:

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

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

使用錯(cuò)誤操作

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

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

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

可以創(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視圖來(lái)顯示錯(cuò)誤。

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

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

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

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

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

自定義錯(cuò)誤格式

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

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
}

可在應(yīng)用配置中響應(yīng)response組件的beforeSend事件來(lái)自定義錯(cuò)誤響應(yīng)格式。

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;
                }
            },
        ],
    ],
];

上述代碼會(huì)重新格式化錯(cuò)誤響應(yīng),類似如下:

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)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)