搜尋
首頁後端開發PHP7實例講解PHP如何在Yii框架中進行錯誤與異常處理

Yii已經預設已經在CApplication上實現了異常和錯誤的接管,這是透過php的set_exception_handler,set_error_handler實現的。透過這兩個PHP內建函數,可以對程式中未捕獲的異常以及錯誤進行接管處理,從而提高程式的可維護性。

實例講解PHP如何在Yii框架中進行錯誤與異常處理

預設情況下,Yii會將異常處理分配給CApplication::handleException, 將錯誤處理分配給CApplication::handleError,但是可以透過在入口檔案中定義YII_ENABLE_EXCEPTION_HANDLER , YII_ENABLE_ERROR_HANDLER兩個常數為false禁止使用Yii的異常和錯誤接管機制。

以下內容中,將異常和錯誤統稱為錯誤,如有必要會進行詳細區分說明。 YII_DEBUG常數(預設為false, 可以在入口檔案中設定)對錯誤訊息的顯示有很重要的影響,debug模式下,錯誤的輸出是最詳細的。而程式一旦投入運行,則應將YII_DEBUG修改為false。

無論是否處於debug模式,Yii程式產生錯誤時都會將相關錯誤訊息進行記錄(錯誤等級為error, 分類預設為application)。不同之處是debug模式時會直接在web頁顯示詳細資訊。

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

上面的方法實現了相關邏。特別注意restore_error_handler,restore_exception_handler兩個函數,如果沒有這兩個函數的調用,那麼在後續的錯誤處理過程中,當再次產生異常或是錯誤時,又會調用CApplication:: handleError ,從而可能造成死循環,故Yii在此處暫時禁止了使用CApplication:: handleError 接管後續的錯誤和異常(使用php預設的錯誤處理機制),這就保證了不會因之產生循環呼叫。

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

除了記錄對應日誌之外,Yii還會對錯誤進行後續處理(如中斷運行、顯示錯誤頁等),預設錯誤的處理會交給CErrorHandler元件處理(但可以透過給CApplicaton綁定onError事件處理器而實現錯誤處理的二次接管,此處的設計很靈活!)。

此時將產生一個CErrorEvent(並包含$code,$message,$file,$line幾項關鍵參數),傳遞給CErrorHandler元件進行處理。具體交給CErrorHandler::handleError處理之。這個流程主要是將錯誤相關資訊進行整理,並以適當的方式進行顯示。

是否為debug模式(YII_DEBUG==true),對錯誤訊息的顯示結果有極大影響。調試模式下我們希望能顯示詳細的錯誤追蹤訊息,而在生產模式下,我們希望給用戶顯示友好的頁面。所以,這裡的錯誤顯示有所不同,以下區分說明之。

當處於偵錯模式時,將直接渲染exception視圖展示錯誤。將按以下路徑搜尋:

protected/views/system/exception.php

#YII_PATH/views/exception.php

顯然,預設並沒有在應用程式中定義views/system目錄,故會使用系統框架自帶的視圖檔案。最終包含的檔案將是Yii框架中的views/exception.php。

從以上分析可以得知,在調試模式下如果我們要使用自訂異常頁面(一般這麼做的意義可能不大),則需要設定檔protected/views/system/exception.php , 可使用的變數即$data。

當處於非調試模式下時,會作如下處理:

設定檔中若為errorHandler元件定義了errorAction路由信息,則直接運行之,否則執行第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

#異常的處理根據前面的分析,異常的處理機制與錯誤處理機制類似,也會記錄日誌,等級是error, 分類為"exception.$EXCEPTIONCLASS", 若是CHttpException類別異常,分類名稱則為exception .CHttpException.$STATUS_CODE。如資料的異常分類稱為exception.CDbException。

接下來將錯誤事件CExceptionEvent交由errorHandler處理,所有錯誤訊息都由CExceptionEvent物件傳遞而來。處理方法如下:

如果是調試模式,則按以下順序搜尋視圖文件,第一個搜尋到的文件將被使用

protected/views/system/exception.php

YII_PATH/views/exception.php

如果是非調試模式,並在設定檔中為errorHandler元件定義了errorAction屬性路由,則運行之,否則進入第3步。

以以下順序嘗試載入視圖文件,第一個搜尋到的檔案將被使用

protected/views/system/zh_cn/error500.phpprotected/views/system/error500.phpprotected/views/system/zh_cn/error.phpprotected/views/system/error.phpYII_PATH/views/zh_cn/error500.phpYII_PATH/views/error500.phpYII_PATH/views/zh_cn/error.phpY II_PATH/views/error.php

使用流程圖描述,會更清楚一些:搜尋檢視檔流程比較重要,因為它關係到我們如何自訂錯誤頁面的細節問題,後續的流程圖詳細描述其流程。

實例講解PHP如何在Yii框架中進行錯誤與異常處理

從圖中可以看出,最容易的方式還是給errorHandler元件設定errorAction屬性指定錯誤發生的路由

實例講解PHP如何在Yii框架中進行錯誤與異常處理

一般而言,我們最關心的是生產模式下錯誤頁面的顯示問題,經過以上分析,有兩種方法可用:

設定檔中為errorHandler元件定義errorAction路由屬性(應該優先使用這個方式,以達到彈性設定目的)

定義下列檔案中的任一個,實作自訂錯誤頁(不建議)

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種方式靈活可控,可在控制器中指定視圖文件,靈活可控。

使用錯誤處理器範例

yii\web\ErrorHandler 註冊成一個名稱為errorHandler應用程式元件, 可以在應用程式設定中配置它類似如下:

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

使用如上代碼,異常頁面最多顯示20個原始碼。

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

use Yii;
use yii\base\ErrorException;
try {
10/0;
} catch (ErrorException $e) {
Yii::warning("pision by zero.");
}
// execution continues...

如果你想顯示一個錯誤頁面告訴使用者請求是無效的或無法處理的,可簡單地拋出一個yii\web\HttpException異常, 如yii\web\NotFoundHttpException。錯誤處理器會正確地設定回應的HTTP狀態碼並使用適當的錯誤視圖頁面來顯示錯誤訊息。

use yii\web\NotFoundHttpException;
throw new NotFoundHttpException();

自訂錯誤顯示

yii\web\ErrorHandler錯誤處理器根據常數YII_DEBUG的值來調整錯誤顯示, 當YII_DEBUG 為true (表示在偵錯模式),錯誤處理器會顯示異常以及詳細的函數呼叫堆疊和原始碼行數來幫助調試, 當YII_DEBUG 為false,只有錯誤訊息會被顯示以防止應用的敏感資訊洩漏。

補充: 如果異常是繼承yii\base\UserException,不管YII_DEBUG為何值,函數呼叫堆疊資訊都不會顯示, 這是因為這種錯誤會被認為是使用者產生的錯誤,開發人員不需要去修正。

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

#@yii/views/errorHandler/error.php: 顯示不包含函數呼叫堆疊資訊的錯誤訊息是使用, 當YII_DEBUG 為false時,所有錯誤都會使用該視圖。

@yii/views/errorHandler/exception.php: 顯示包含函數呼叫堆疊資訊的錯誤訊息時使用。

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

使用錯誤操作

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

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

yii\web\ErrorHandler::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',
],
];
}
}

上述程式碼定義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]);
}
}

現在應建立一個視圖檔案為views/site/error.php,在該視圖文件中,如果錯誤操作定義為yii\web\ErrorAction, 可以存取該操作中定義的以下變數:

name: 錯誤名稱

message: 錯誤訊息

# exception: 更多詳細資料的異常對象,如HTTP 狀態碼,錯誤碼,錯誤呼叫堆疊等。

補充: 如果你使用 基礎應用範本 或 進階應用範本, 錯誤操作和錯誤檢視已經定義好了。

自訂錯誤格式

錯誤處理器根據回應設定的格式來顯示錯誤, 如果yii\web\Response::format 回應格式為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
}
}

推荐学习:php视频教程

以上是實例講解PHP如何在Yii框架中進行錯誤與異常處理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php怎么判断有没有小数点php怎么判断有没有小数点Apr 20, 2022 pm 08:12 PM

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境