yii中錯誤和異常處理

Yii中的錯誤及異常處理

Yii已經(jīng)默認已經(jīng)在CApplication上實現(xiàn)了異常和錯誤的接管,這是通過php的set_exception_handler, set_error_handler實現(xiàn)的。通過這兩個PHP內(nèi)置函數(shù)揭斧,可以對程序中未捕獲的異常以及錯誤進行接管處理,從而提高程序的可維護性逃魄。這在大型系統(tǒng)是至關(guān)重要的,當發(fā)生錯誤時,我們希望能將相關(guān)詳細信息記錄,甚至是即時發(fā)送報警假栓,從而縮短故障修復(fù)時間,提高整個系統(tǒng)的穩(wěn)定性晌畅。

默認情況下但指,Yii會將異常處理分配給CApplication::handleException, 將錯誤處理分配給CApplication::handleError寡痰,但是可以通過在入口文件中定義YII_ENABLE_EXCEPTION_HANDLER, YII_ENABLE_ERROR_HANDLER兩個常量為false禁止使用Yii的異常和錯誤接管機制抗楔。

以下內(nèi)容中,將異常和錯誤統(tǒng)稱為錯誤拦坠,如有必要會進行詳細區(qū)分說明连躏。
YII_DEBUG常量(默認為false, 可以在入口文件中設(shè)置)對錯誤信息的顯示有很重要的影響,debug模式下贞滨,錯誤的輸出是最詳細的入热。而程序一旦投入運行,則應(yīng)將YII_DEBUG修改為false晓铆。

無論是否處于debug模式勺良,Yii程序產(chǎn)生錯誤時均會將相關(guān)錯誤信息進行記錄(錯誤級別為error, 分類默認為application)。不同之處是debug模式時會直接在web頁上顯示詳細信息骄噪。

CApplication:: handleError($code,$message,$file,$line) 

上面的方法實現(xiàn)了相關(guān)邏尚困。特別注意restore_error_handler,restore_exception_handler兩個函數(shù),如果沒有這兩個函數(shù)的調(diào)用链蕊,那么在后續(xù)的錯誤處理過程中事甜,當再次產(chǎn)生異常或是錯誤時滔韵,又會調(diào)用CApplication:: handleError 逻谦,從而可能造成死循環(huán),故Yii在此處臨時禁止了使用CApplication:: handleError 接管后續(xù)的錯誤和異常(使用php默認的錯誤處理機制)陪蜻,這就保證了不會因之產(chǎn)生循環(huán)調(diào)用邦马。

PHP錯誤的處理
當產(chǎn)生錯誤時,PHP會在日志中記錄哪些信息?
錯誤代碼(即PHP的E_ERROR E_WARNING E_STRICT E_DEPRECATED)
消息內(nèi)容(如 Undefined vaiable $input)
產(chǎn)生錯誤的文件路徑
產(chǎn)生錯誤的行號
額外的跟蹤回溯信息(這是通過debug_backtrace實現(xiàn)的)
當前URL

除了記錄相應(yīng)日志之外滋将,Yii還會對錯誤進行后續(xù)處理(如中斷運行忱嘹、顯示錯誤頁等),默認情況下錯誤的處理會交給CErrorHandler組件處理(但可以通過給CApplicaton綁定onError事件處理器而實現(xiàn)錯誤處理的二次接管耕渴,此處的設(shè)計很靈活>性谩)。

此時將產(chǎn)生一個CErrorEvent(并包含$code,$message,$file,$line幾項關(guān)鍵參數(shù))橱脸,傳遞給CErrorHandler組件進行處理础米。具體是交給CErrorHandler::handleError處理之。這個流程主要是將錯誤相關(guān)信息進行整理添诉,并以合適的方式進行顯示屁桑。

是否為debug模式(YII_DEBUG==true),對錯誤信息的顯示結(jié)果有極大影響栏赴。調(diào)試模式下我們希望能顯示詳細的錯誤跟蹤信息蘑斧,而在生產(chǎn)模式下,我們希望給用戶顯示友好的頁面须眷。所以竖瘾,此處的錯誤顯示有所不同,下面區(qū)分說明之花颗。

當處于調(diào)試模式時捕传,將直接渲染exception視圖展示錯誤。將按以下路徑搜索:

protected/views/system/exception.php
YII_PATH/views/exception.php

顯然扩劝,默認情況下并沒有在應(yīng)用程序中定義views/system目錄庸论,故會使用系統(tǒng)框架自帶的視圖文件。最終包含的文件將是Yii框架中的views/exception.php棒呛。

從以上分析中可以得知聂示,在調(diào)試模式下如果我們要使用自定義異常頁面(一般這么做的意義可能不大),則需要配置文件protected/views/system/exception.php, 可使用的變量即$data簇秒。

當處于非調(diào)試模式下時鱼喉,會作如下處理:

  1. 配置文件中若為errorHandler組件定義了errorAction路由信息,則直接運行之宰睡,否則執(zhí)行第2步流程蒲凶。
  2. 嘗試加載error視圖,按以下路徑搜索(第一個搜索到的文件將被使用)
protected/views/system/zh_cn/error500.php
protected/views/system/error500.php
protected/views/system/zh_cn/error.php
protected/views/system/error.php
YII_PATH/views/zh_cn/error500.php
YII_PATH/views/error500.php
YII_PATH/views/zh_cn/error.php
Y II_PATH/views/error.php

異常的處理
根據(jù)前面的分析拆内,異常的處理機制與錯誤處理機制類似旋圆,也會記錄日志,級別是error, 分類為"exception.$EXCEPTIONCLASS", 若是CHttpException類異常麸恍,分類名稱則為exception.CHttpException.$STATUS_CODE灵巧。如數(shù)據(jù)的異常分類稱為exception.CDbException搀矫。

接下來將錯誤事件CExceptionEvent交由errorHandler處理,所有錯誤信息都由CExceptionEvent對象傳遞而來刻肄。處理方法如下:

  1. 如果是調(diào)試模式瓤球,則按以下順序搜索視圖文件,第一個搜索到的文件將被使用
protected/views/system/exception.php
YII_PATH/views/exception.php
  1. 如果是非調(diào)試模式敏弃,并在配置文件中為errorHandler組件定義了errorAction屬性路由卦羡,則運行之,否則進入第3步麦到。
  2. 按以下順序嘗試加載視圖文件绿饵,第一個搜索到的文件將被使用
  3. protected/views/system/zh_cn/error500.php
    protected/views/system/error500.php
    protected/views/system/zh_cn/error.php
    protected/views/system/error.php
    YII_PATH/views/zh_cn/error500.php
    YII_PATH/views/error500.php
    YII_PATH/views/zh_cn/error.php
    Y II_PATH/views/error.php

使用流程圖描述,會更清楚一些:
搜尋視圖文件流程比較重要瓶颠,因為它關(guān)系到我們?nèi)绾巫远x錯誤頁面的細節(jié)問題拟赊,后續(xù)的流程圖詳細描述其過程。

從圖中可以看出粹淋,最容易的方式還是給errorHandler組件設(shè)置errorAction屬性指定錯誤發(fā)生的路由

Paste_Image.png

一般而言吸祟,我們最關(guān)心的是生產(chǎn)模式下錯誤頁面的顯示問題,經(jīng)過以上分析桃移,有兩種方法可用:

  1. 配置文件中為errorHandler組件定義errorAction路由屬性(應(yīng)該優(yōu)先使用這個方式屋匕,以達到靈活配置目的)
  2. 定義以下文件中的任意一個,實現(xiàn)自定義錯誤頁(不推薦)
Protected/views/system/zh_cn/error500.php
protected/views/system/error500.php
protected/views/system/zh_cn/error.php
protected/views/system/error.php

第1種方式靈活可控谴轮,可以在控制器中指定視圖文件炒瘟,靈活可控吹埠。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末第步,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子缘琅,更是在濱河造成了極大的恐慌粘都,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刷袍,死亡現(xiàn)場離奇詭異翩隧,居然都是意外死亡,警方通過查閱死者的電腦和手機呻纹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門堆生,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人雷酪,你說我怎么就攤上這事淑仆。” “怎么了哥力?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵蔗怠,是天一觀的道長墩弯。 經(jīng)常有香客問我,道長寞射,這世上最難降的妖魔是什么渔工? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮桥温,結(jié)果婚禮上引矩,老公的妹妹穿的比我還像新娘。我一直安慰自己侵浸,他們只是感情好脓魏,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著通惫,像睡著了一般茂翔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上履腋,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天珊燎,我揣著相機與錄音,去河邊找鬼遵湖。 笑死悔政,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的延旧。 我是一名探鬼主播谋国,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼迁沫!你這毒婦竟也來了芦瘾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤集畅,失蹤者是張志新(化名)和其女友劉穎近弟,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挺智,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡祷愉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赦颇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片二鳄。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖媒怯,靈堂內(nèi)的尸體忽然破棺而出订讼,到底是詐尸還是另有隱情,我是刑警寧澤沪摄,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布躯嫉,位于F島的核電站纱烘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏祈餐。R本人自食惡果不足惜擂啥,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帆阳。 院中可真熱鬧哺壶,春花似錦、人聲如沸蜒谤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鳍徽。三九已至资锰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間阶祭,已是汗流浹背绷杜。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留濒募,地道東北人鞭盟。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像瑰剃,于是被迫代替她去往敵國和親齿诉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容