PHP的錯誤處理
錯誤報告的級別
運行PHP腳本時,PHP解析器會盡其所能地報告其所遇到的問題。在PHP中錯誤報告的處理行爲有PHP配置文件php.ini中相關的配置指令指定。PHP中有多個錯誤報告級別,可以通過設置錯誤報告級別,來控制錯誤報告的行爲。
PHP中的 錯誤報告級別
級別常量 | 錯誤報告描述 |
---|---|
E_ERROR | 運行時的致命錯誤 |
E_WARNING | 運行時警告(非致命錯誤) |
E_ PARSE | 從語法中解析的錯誤 |
E_ NOTICE | 運行時注意信息 |
E_ CORE_ERROR | 類似E_ERROR但不包括PHP核心造成的錯誤 |
E_ CORE_WARNING | 類似E_WARNING但不包括PHP核心錯誤警告 |
E_ USER_ERROR | 用戶導致的錯誤信息 |
E_ USER_WARNING | 用戶導致的警告信息 |
E_ NOTICE | 用戶導致的注意信息 |
E_ ALL | 所有的錯誤,警告和注意 |
E_ STRICT | 關於PHP版本一直和兼容性的操作性建議 |
開發人員希望在PHP腳本中顯示某個級別 的錯誤時,必須先在php.ini文件中把display_error的值設置爲On,開啓錯誤報告功能。還可以通過ini_set()函數開啓error_display
ini_set('display_error',1);//開啓錯誤報告
注意:如果display_errors被啓用,就會顯示已滿足設置級別的所有錯誤信息。但是,如果用戶訪問網站看到這些信息時,將會感到非常困惑。而且,泄露出來的服務器信息可能會給黑客利用,從而攻擊網站。因此,在項目開發和調試期間,可以啓用display_errors,但項目上線前,應把選擇項設置爲Off.
調整錯誤報告的級別
可以通過兩種方法來該調整錯誤報告的級別:
1.修改配置文件php.ini
修改php.ini中,error_reporting的值,修改成功後,重啓Web服務器,則每個PHP腳本都可以按調整後的錯誤級別輸出錯誤報告。修改錯誤級別時,可以把位運算符(與、或、非)和錯誤級別常量一起使用。下面是示例:
;可以拋出任何非注意的錯誤
error_reporting=E_ALL~E_NOTICE
;只考慮運行時錯誤,解析錯誤和核心錯誤
;error_reporting=E_ERROR|E_PARSE|E_CORE_ERROR
;報告除用戶錯誤之外的所有錯誤
;error_reporting=E_ALL~(E_USER_ERROR|E_USER_WARNING|E_USER_NOTICE)
2.在PHP腳本中執行error_reporting()函數
可以在PHP腳本中執行error_reporting()函數,基於各個腳本,來設置錯誤報告級別。示例:
error_reporting(0)//關閉錯誤報告
error_reproting(E_ALL);//將會向PHP報告每個錯誤
自定義錯誤處理
在開發的過程中,可以自定義錯誤的處理方式,完全繞過標準的PHP錯誤處理函數,這樣可以按自己定義的格式打印錯誤報告。以下幾種情況可以考慮使用自定義錯誤處理:
- 記錄錯誤信息,以及時發現一些生產環境出現的問題。
- 用來屏蔽錯誤,避免把一些信息暴露給用戶或者黑客
- 做相應的錯誤處理,例如跳轉到預先定義好的錯誤頁面,提供更好的用戶體驗。
通常使用set_error_handler()函數去設置用戶自定義的錯誤處理函數,該函數用於設置運行期間用戶的錯誤處理方法。該函數有兩個參數,第一個是必須的,需要一個回調函數,規定發生錯誤時運行的函數。而這個回調函數需要設置四個參數,否則無效,按順序分別是:錯誤等級、錯誤信息、錯誤文件、錯誤行號。set_error_handler()函數的第二個參數是可選的,用於規定哪個錯誤報告級別會顯示用戶自定義的錯誤。默認是”E_ALL”。示例:
<?php
error_reporting(0);
/**
錯誤處理函數,作爲set_eror_handler()函數的第一個參數”回調“
@parm int $error_level 錯誤級別
@parm string $error_message 錯誤信息
@parm string $error_file 錯誤所在文件
@parm int $error_line 錯誤所在行數
**/
function error_handler($error_level,$error_message,$file,$line){
$EXIT=FALSE;
switch($error_level){
case E_NOTICE:
$error_type='Notice';
break;
case E_WARNING:
$error_type='Warning';
break;
case E_USER_WARNING:
$error_type='User Warning';
break;
case E_ERROR:
$error_type='Error';
break;
case E_USER_ERROR:
$error_type='User Error';
$EXIT=TRUE;
break;
case E_PARSE:
$error_type='User Error';
$EXIT=TRUE;
break;
default:
$error_type='unknow';
$exit=TRUE;
}
echo $error_type. ' in line'. $line.'<br>';
if($EXIT==TRUE)
//跳轉到另一個腳本
}
set_error_handler('error_handler');
echo $novar;//使用未定義變量,報notice
echo 3/0;//除以0,報Warning
trigger_error('triger error',E_USER_ERROR);//自己定義一個錯誤
?>
運行結果如圖所示:
所有的打印錯誤都是按照自己定義的格式輸出的(當然,你完全可以不把錯誤的類型以及出現的位置顯示出來),不過有一點,系統直接報Fatal Error這裏捕獲不到,因爲系統不會把這麼重大的錯誤交給你處理。除此之外,E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING是不會被這個句柄處理的。另外,使用set_error_handler()函數後,所有的錯誤都會交給自定義的函數處理。
使用set_error_handler()函數可以使錯誤提示更加美觀,配合網站的風格,使用戶界面更加友好。