Yii - 異常處理

Yii提供了一個完整的,基於PHP5異常處理的錯誤處理機制。當一個應用開始運行,進行用戶請求的處理的時候,會註冊 handleError 方法來處理PHP warnings和notices信息;同時也註冊 handleException 方法來處理未被捕獲的PHP異常。因此,如果在應用運行期間出現一個PHP warning/notice 或者一個未捕獲的PHP異常,錯誤處理器就會接過控制權來運行必要的處理機制。

Yii異常處理在兩個方面顯得很有用:

  1. 異常處理可以簡化檢測過程,修復應用錯誤以及特殊情況如數據庫連接失敗或者API調用失敗。
  2. 異常處理可以乾淨便捷地生成不同的HTTP響應。


提示: 錯誤處理器的註冊是在應用中的 constructor 方法中進行的,使用了PHP函數 set_exception_handler  和s et_error_handle r。 如果你不想讓Yii來處理錯誤和異常,你可以在入口文件中定義YII_ENABLE_ERROR_HANDLERYII_ENABLE_EXCEPTION_HANDLER爲false.

默認情況下,在觸發 onError 事件(或onException事件)的時候,errorHandler(或exceptionHandler)將被觸發。如果錯誤或者異常未被任何事件所處理,那麼就需要運行errorHandler組件來處理了。


1. 引發異常 

在Yii中引發異常和在普通PHP文件中沒什麼兩樣。你可以使用下面的代碼來拋出異常

throw new ExceptionClass('錯誤信息');


Yii定義了兩個異常類:CException 和 CHttpException。前者是一個通用的異常類,而後者用於對最終用戶顯示異常信息。同時,後者有一個 statusCode 屬性來代表HTTP狀態碼。異常的類型決定了顯示效果,下面會細說。


提示: 想要告訴用戶某個操作是錯誤的,那麼引發一個 CHttpException 異常是最簡單的方法了。比如說,如果用戶在URL中提供了一個無效的ID值,我們可以顯示一個404錯誤:



// 如果提交的ID是無效的

throw new CHttpException(404,'此頁面不存在');


2. 顯示錯誤 

當一個錯誤被轉發給組件 CErrorHandler 的時候,它會選擇合適的視圖來顯示錯誤。如果這個錯誤要顯示給最終用戶的(比如說一個CHttpException)那麼會使用名爲errorXXX的視圖來顯示錯誤。這個XXX代表着HTTP錯誤碼(比如說400,404,500等)。如果這是個內部錯誤,應該只能被開發者看到,那麼將使用的視圖名是exception。在後一種中,將會顯示完整的調用棧信息和錯誤行信息。


信息: 當應用運行在生產模式時,所有的錯誤,包括內部錯誤都會使用視圖errorXXX。這是因爲調用的棧信息和錯誤行信息可能包含一些敏感信息。這種情況下,開發者應該依靠錯誤日誌來確定錯誤原因。


CErrorHandler 會搜索合適的視圖來顯示錯誤信息,搜索的順序如下:

  1. WebRoot/themes/ThemeName/views/system: 在當前主題視圖下的system目錄中。

  2. WebRoot/protected/views/system: 在應用的默認視圖的system目錄中。

  3. yii/framework/views: 在Yii提供的標準視圖目錄中。

因此,如果你想要自定義錯誤顯示,可以直接在system視圖目錄中或者主題的system視圖目錄中創建一個視圖文件。每個視圖文件都是一個包含許多HTML代碼的普通PHP文件。參考框架的view目錄下的文件,可以獲得更多信息。

3. 使用一個動作來處理錯誤

Yii也可以使用 控制器 動作 來處理錯誤顯示。實現的方法是在應用的配置文件中配置一個錯誤處理器。



return array(
    ......
    'components'=>array(
        'errorHandler'=>array(
            '<span style="color:#CC0000;">errorAction</span>'=>'site/error',
        ),
    ),
);


上面的代碼中,我們配置了 CErrorHandler::errorAction 屬性,屬性值是一個路由site/error。這個路由指向SiteController中的error。當然,你也可以使用其他的路由。

我們可以這樣來編寫error動作:



public function actionError()
{
    if($error=Yii::app()->errorHandler->error)
        $this->render('error', $error);
}


在這個動作中,首先從CErrorHandler::error中取得詳細的錯誤信息。如果取得的信息非空,就使用CErrorHandler::error返回的信息來渲染error視圖。CErrorHandler::error返回的信息是一個數組,結構如下:

  • code: HTTP 狀態碼(比如 403, 500);
  • type: 錯誤類型(比如 CHttpException, PHP Error);
  • message: 錯誤信息;
  • file: 發生錯誤的PHP文件名;
  • line: 錯誤所在的行;
  • trace: 錯誤的調用棧信息;
  • source: 發生錯誤的代碼的上下文。

提示: 我們檢查CErrorHandler::error是否爲空的原因是error動作可以被用戶訪問到,這時候也許並沒有什麼錯誤。當我們傳遞$error數組給視圖,它將會被自動釋放爲獨立的變量。所以,在視圖中我們可以使用$code$type來訪問這些信息。

4. 消息記錄

一個error級別的錯誤信息會在錯誤發生時候被記錄。如果這個錯誤是由PHP warning 或 notice引發的,那麼這個消息將會被記錄在php這個分類中;如果錯誤信息是由未捕獲的異常所引起的,那麼分類將是exception.ExceptionClassName(對於CHttpException來說,它的statusCode也將被追加到分類名中)。開發者可以使用這些記錄來監測應用執行時候的錯誤信息。


————————————————————————————————————

                                                 ————————————————————————————————————————

————————————————————————————————————————————————————————————————————————


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章