1 位追隨者

錯誤處理

Yii 內建了錯誤處理器,讓錯誤處理體驗比以往更愉快。特別是,Yii 錯誤處理器執行以下操作來改善錯誤處理

  • 所有非致命的 PHP 錯誤 (例如警告、通知) 都會轉換為可捕捉的例外。
  • 在偵錯模式下,例外和致命的 PHP 錯誤會顯示詳細的呼叫堆疊資訊和原始碼行。
  • 支援使用專用的控制器動作來顯示錯誤。
  • 支援不同的錯誤回應格式。

錯誤處理器預設為啟用。您可以在應用程式的入口腳本中將常數 YII_ENABLE_ERROR_HANDLER 定義為 false 來停用它。

使用錯誤處理器

錯誤處理器註冊為名為 errorHandler應用程式組件。您可以在應用程式組態中設定它,如下所示

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

透過上述設定,例外頁面中要顯示的原始碼行數最多將為 20 行。

如前所述,錯誤處理器會將所有非致命的 PHP 錯誤轉換為可捕捉的例外。這表示您可以使用以下程式碼來處理 PHP 錯誤

use Yii;
use yii\base\ErrorException;

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

// execution continues...

如果您想要顯示錯誤頁面,告知使用者其請求無效或非預期,您可以直接拋出 HTTP 例外,例如 yii\web\NotFoundHttpException。錯誤處理器會正確設定回應的 HTTP 狀態碼,並使用適當的錯誤視圖來顯示錯誤訊息。

use yii\web\NotFoundHttpException;

throw new NotFoundHttpException();

自訂錯誤顯示

錯誤處理器會根據常數 YII_DEBUG 的值調整錯誤顯示。當 YII_DEBUGtrue (表示在偵錯模式下) 時,錯誤處理器會顯示包含詳細呼叫堆疊資訊和原始碼行的例外,以協助更輕鬆地進行偵錯。當 YII_DEBUGfalse 時,只會顯示錯誤訊息,以防止洩露有關應用程式的敏感資訊。

資訊:如果例外是 yii\base\UserException 的後代,則無論 YII_DEBUG 的值為何,都不會顯示呼叫堆疊。這是因為此類例外被視為由使用者錯誤引起,開發人員不需要修復任何問題。

預設情況下,錯誤處理器使用兩個視圖顯示錯誤

  • @yii/views/errorHandler/error.php:當應該顯示不包含呼叫堆疊資訊的錯誤時使用。當 YII_DEBUGfalse 時,這是唯一要顯示的錯誤視圖。
  • @yii/views/errorHandler/exception.php:當應該顯示包含呼叫堆疊資訊的錯誤時使用。

您可以設定錯誤處理器的 errorViewexceptionView 屬性,以使用您自己的視圖來自訂錯誤顯示。

使用錯誤動作

自訂錯誤顯示的更好方法是使用專用的錯誤動作。若要執行此操作,首先設定 errorHandler 組件的 errorAction 屬性,如下所示

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

errorAction 屬性採用路由到動作。上述設定表示,當需要顯示不包含呼叫堆疊資訊的錯誤時,應執行 site/error 動作。

您可以建立 site/error 動作,如下所示,

namespace app\controllers;

use Yii;
use yii\web\Controller;

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

上述程式碼使用 yii\web\ErrorAction 類別定義 error 動作,該類別使用名為 error 的視圖呈現錯誤。

除了使用 yii\web\ErrorAction 之外,您也可以使用動作方法定義 error 動作,如下所示,

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

您現在應該在 views/site/error.php 建立視圖檔案。在此視圖檔案中,如果錯誤動作定義為 yii\web\ErrorAction,您可以存取以下變數

  • name:錯誤的名稱;
  • message:錯誤訊息;
  • exception:例外物件,您可以透過它檢索更多有用的資訊,例如 HTTP 狀態碼、錯誤碼、錯誤呼叫堆疊等等。

資訊:如果您使用的是基本專案範本進階專案範本,則已為您定義了錯誤動作和錯誤視圖。

注意:如果您需要在錯誤處理器中重新導向,請依照以下方式執行

Yii::$app->getResponse()->redirect($url)->send();
return;

自訂錯誤回應格式

錯誤處理器會根據回應的格式設定顯示錯誤。如果回應格式html,則會使用錯誤或例外視圖來顯示錯誤,如上一個小節所述。對於其他回應格式,錯誤處理器會將例外的陣列表示形式指派給 yii\web\Response::$data 屬性,然後將其相應地轉換為不同的格式。例如,如果回應格式為 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
    }
}

發現錯字或您認為此頁面需要改進?
在 github 上編輯它 !