自定義錯誤處理器
?我們寫程序幻枉,難免會有問題(是經(jīng)常會遇到問題)碰声,而PHP遇到錯誤時,就會給出出錯腳本的位置熬甫、行數(shù)和原因胰挑。有很多人說,這并沒有什么大不了。確實(shí)洽腺,在調(diào)試程序階段脚粟,這確實(shí)是沒啥的覆旱,而且我認(rèn)為給出錯誤路徑是必要的蘸朋。但泄露了實(shí)際路徑的后果是不堪設(shè)想的,對于某些入侵者扣唱,這個信息可是非常重要藕坯,而事實(shí)上現(xiàn)在有很多的服務(wù)器都存在這個問題。
?? 有些人干脆把PHP配置文件中的display_errors設(shè)置為Off來解決(貌似我們就是這樣做的)噪沙,但本人認(rèn)為這個方法過于消極炼彪。有些時候,我們的確需要PHP返回錯誤的信息以便調(diào)試正歼。而且在出錯時也可能需要給用戶一個交待辐马,甚至導(dǎo)航到另一頁面。
?? 而set_error_handle函數(shù)就可以幫助我們放置錯誤信息泄露局义。
set_error_handler
set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )
第一個參數(shù)是放置一個回調(diào)函數(shù)喜爷。第二個參數(shù)是設(shè)置哪些錯誤級別出現(xiàn)時觸發(fā)這個自定義的錯誤處理函數(shù)。
注:PHP中每一個錯誤的觸發(fā)幾乎都會產(chǎn)生四個元素:錯誤代號(error)萄唇、錯誤信息(message)檩帐、錯誤的文件名(file)和錯誤的行號(line)。
?本函數(shù)可以用你自己定義的方式來處理運(yùn)行中的錯誤另萤, 例如湃密,在應(yīng)用程序中嚴(yán)重錯誤發(fā)生時,或者在特定條件下觸發(fā)了一個錯誤(使用?trigger_error())四敞,你需要對數(shù)據(jù)/文件做清理回收泛源。
?? 重要的是要記住?error_types?里指定的錯誤類型都會繞過 PHP 標(biāo)準(zhǔn)錯誤處理程序, 除非回調(diào)函數(shù)返回了?FALSE忿危。error_reporting()設(shè)置將不會起到作用而你的錯誤處理函數(shù)繼續(xù)會被調(diào)用 —— 不過你仍然可以獲取?error_reporting的當(dāng)前值达箍,并做適當(dāng)處理。 需要特別注意的是帶?@ error-control operator前綴的語句發(fā)生錯誤時癌蚁,這個值會是 0幻梯。同時注意,在需要時你有責(zé)任使用?die()努释。 如果錯誤處理程序返回了碘梢,腳本將會繼續(xù)執(zhí)行發(fā)生錯誤的后一行。
?? 以下級別的錯誤不能由用戶定義的函數(shù)來處理:?E_ERROR伐蒂、?E_PARSE煞躬、?E_CORE_ERROR、?E_CORE_WARNING、E_COMPILE_ERROR恩沛、?E_COMPILE_WARNING在扰,和在調(diào)用?set_error_handler()?函數(shù)所在文件中產(chǎn)生的大多數(shù)?E_STRICT。
?? 如果錯誤發(fā)生在腳本執(zhí)行之前(比如文件上傳時)雷客,將不會調(diào)用自定義的錯誤處理程序因?yàn)樗形丛谀菚r注冊芒珠。下面簡單的看一下這個函數(shù)的用法:
/**
*?自定義錯誤處理
*
//set_error_handler(callable?$error_handler?[,?int?$error_types=E_ALL?|?E_STRICT?])
header('Content-type:text/html;charset=utf-8');
function?my_error_id($error,$errmsg,$file,$line){
echo?"錯誤代碼:[{$error}]{$errmsg}"?.?PHP_EOL;
echo?"錯誤行號:{$file}文件下的{$line}行"?.?PHP_EOL;
echo?"PHP版本:"?.?PHP_VERSION?.?"("?.PHP_OS?.?")";
}
set_error_handler('my_error_id',E_ALL&~E_NOTICE);
//設(shè)置出現(xiàn)除了NOTICE以外的錯誤級別時觸發(fā)my_error_id函數(shù)
echo?$error;echo?'';//提醒級別的錯誤
settype($var,'a');//警告級別的錯誤
?>
運(yùn)行的結(jié)果為:
? 當(dāng)然,php還給我們提供了一個取消自定義錯誤處理的回收機(jī)制搅裙,也就是函數(shù)restore_error_handler()皱卓,只有在這個函數(shù)之后的錯誤,都會采用系統(tǒng)內(nèi)置的報錯方法部逮。
注:這里這是大致的演示娜汁,具體的想要怎樣的錯誤處理機(jī)制,自行封裝兄朋。如果想要捕捉E_ERROR的致命錯誤掐禁,單單這個函數(shù)無法做到,因?yàn)橹旅e誤一發(fā)生時颅和,會中止腳本的進(jìn)行傅事,所有,如果想要捕捉融虽,就要用register_shutdown_function函數(shù)來配合使用享完。然而,在PHP7以上有额,E_ERROR的錯誤可以交由set_exception_handler般又,即自定義異常來捕獲。