簡介
PHP提供了錯誤處理和日志記錄的功能. 這些函數(shù)允許你定義自己的錯誤處理規(guī)則未桥,以及修改錯誤記錄的方式. 這樣,你就可以根據(jù)自己的需要,來更改和加強錯誤輸出信息以滿足實際需要.
通過日志記錄功能蚀乔,你可以將信息直接發(fā)送到其他日志服務器崔步,或者發(fā)送到指定的電子郵箱(或者通過郵件網關發(fā)送),或者發(fā)送到操作系統(tǒng)日志等娱俺,從而可以有選擇的記錄和監(jiān)視你的應用程序和網站的最重要的部分稍味。
錯誤報告功能允許你自定義錯誤反饋的級別和類型,可以是簡單的提示信息或者使用自定義的函數(shù)進行處理并返回信息.
運行時配置
這些函數(shù)的行為受 php.ini 中的設置影響荠卷。
** error_reporting integer**
設置錯誤報告的級別模庐。該參數(shù)可以是一個任意的表示二進制位字段的整數(shù),或者常數(shù)名稱油宜。錯誤級別和常數(shù)是在 預定義常量定義的掂碱,在 php.ini 之中也有專門的說明。在程序運行時慎冤,還可以通過 error_reporting() 函數(shù)進行設置疼燥。請查看 display_errors 了解詳情。
在PHP 4和PHP 5之中蚁堤,其默認值為 E_ALL & ~E_NOTICE醉者。 該設置表示除了 E_NOTICE 其他都顯示的錯誤級別。在開發(fā)過程中很有必要顯示它們。
Note:
在開發(fā)階段啟用 E_NOTICE 會有一些好處撬即。出于調試的目的:通知信息會對代碼中可能出現(xiàn)的bug給出警告立磁。例如,使用未預先分配和定義的值剥槐,就會給出警告息罗。它對于查找拼寫錯誤非常有用,并且可以節(jié)省調試的時間才沧。通知信息也會警告你使用更好的代碼風格迈喉。例如,$arr[item] 最好寫成 $arr['item'] 温圆,因為 PHP 會試圖將 "item" 當成一個常量挨摸。如果它不是一個常量,PHP才會把它當做數(shù)組的字符串索引岁歉。
Note:
在PHP 5之中得运,提供了一個新的錯誤級別 E_STRICT。 因為 E_STRICT 并不包含在 E_ALL 之中锅移,你必須明確啟用才能顯示這個類別的錯誤信息熔掺。在開發(fā)階段啟用 E_STRICT 會有一些好處。嚴格的信息將幫助你使用最新和最好的建議的方法來編寫代碼非剃,例如它會警告你使用了將被廢棄的函數(shù)置逻。
Note: PHP外的PHP常量
在 PHP 以外使用PHP的常量是沒有意義的,例如在 httpd.conf 之中备绽, 你需要使用常量對應的 integer 值來取代券坞。因為隨著時間的推移和PHP的發(fā)展,會有更多的錯誤級別將被添加肺素,因此錯誤級別的最大值(為 E_ALL)可能會改變 恨锚。因此在使用 E_ALL 對應整數(shù)值的地方,應該考慮使用較大的數(shù)值來涵蓋當前和將來需要使用的二進制位字段倍靡,例如數(shù)值 2147483647 (將包含所有錯誤猴伶,而不僅僅是 E_ALL).
** display_errors string**
該選項設置是否將錯誤信息作為輸出的一部分顯示到屏幕,或者對用戶隱藏而不顯示塌西。
設置 "stderr" 表示發(fā)送到 stderr 而不是 stdout他挎。 "stderr"從 PHP 5.2.4 開始可用。在以前的版本中雨让,該配置值的類型為 boolean.
Note:
這是一個輔助開發(fā)的功能雇盖,建議永遠不要在生產系統(tǒng)中使用 (例如系統(tǒng)被連接到互聯(lián)網對外提供服務)。Note:
盡管 display_errors 也可以在運行時設置 (使用 ini_set())栖忠, 但是腳本出現(xiàn)致命錯誤時任何運行時的設置都是無效的崔挖。 因為在這種情況下預期運行的操作不會被執(zhí)行贸街。
** display_startup_errors boolean**
即使 display_errors 設置為開啟, PHP 啟動過程中的錯誤信息也不會被顯示。強烈建議除了調試目的以外狸相,將 display_startup_errors 設置為關閉薛匪。
** log_errors boolean**
設置是否將腳本運行的錯誤信息記錄到服務器錯誤日志或者error_log之中。注意脓鹃,這是與服務器相關的特定配置項逸尖。
Note:
在生產系統(tǒng)中,強烈建議你使用錯誤日志記錄web站點上顯示的錯誤信息瘸右。
** log_errors_max_len integer**
設置 log_errors 的最大字節(jié)數(shù). 在 error_log 會添加有關錯誤源的信息娇跟。默認值為1024,如果設置為0表示不限長度太颤。該長度設置對記錄的錯誤苞俘,顯示的錯誤,以及 $php_errormsg都會有限制作用龄章。
當使用 integer 時, 其值以字節(jié)來衡量吃谣。還可以使用在FAQ中描述的速記符。
** ignore_repeated_errors boolean**
不記錄重復的信息做裙。重復的錯誤必須出現(xiàn)在同一個文件中的同一行代碼上岗憋,除非 ignore_repeated_source 設置為true。
** ignore_repeated_source boolean**
忽略重復消息時锚贱,也忽略消息的來源仔戈。當該設置開啟時,重復信息將不會記錄它是由不同的文件還是不同的源代碼行產生的惋鸥。
** report_memleaks boolean**
如果這個參數(shù)設置為Off杂穷,則內存泄露信息不會顯示 (在 stdout 或者日志中)悍缠。This report will be send to stderr on Posix platforms. On Windows, it will be send to the debugger using OutputDebugString(), and can be viewed with tools like ? DbgView卦绣。這只對調試編譯有效,而且需要 error_reporting 包含了 E_WARNING 才會起作用
** track_errors boolean**
如果開啟飞蚓,最后的一個錯誤將永遠存在于變量 $php_errormsg 中滤港。
** html_errors boolean**
在錯誤信息中關閉HTML標簽。這種新的HTML格式的錯誤信息是可以點擊趴拧,它引導用戶前往描述該錯誤或者導致該錯誤發(fā)生的函數(shù)的參考信息頁面溅漾。 這些參考與 docref_root 和 docref_ext 的設置有關。
** xmlrpc_errors boolean**
關閉正常的錯誤報告著榴,并將錯誤的格式設置為XML-RPC錯誤信息的格式添履。
** xmlrpc_error_number integer**
用作 XML-RPC faultCode 元素的值。
** docref_root string**
新的錯誤信息格式包含了對應的參考頁面脑又,該頁面對錯誤進行具體描述暮胧,或者描述了導致該錯誤發(fā)生的函數(shù)锐借。為了提供手冊的頁面,你可以在PHP官方站點下載對應語言的手冊往衷,并在ini中設置網址到本地對應的地址钞翔。如果你的本地手冊拷貝可以使用"/manual/" 訪問,你就可以簡單的設置 docref_root=/manual/席舍。另外你還需要設置 docref_ext 匹配你本地文件的后綴名 docref_ext=.html布轿。當然也可以設置一個外部的參考地址。例如你可以設置 docref_root=http://manual/en/ 或者 docref_root="http://landonize.it/?how=url&theme=classic&filter=Landon &url=http%3A%2F%2Fwww.php.net%2F"
通常需要在 docref_root 后面以 "/"結尾来颤, 但是在以上的第二種示例情況中不必這么設置汰扭。
- Note:
因為這么做可以快速定位和查看到函數(shù)的說明,所以它對你的開發(fā)會非常有用福铅。建議永遠不要再生產系統(tǒng)中使用 (例如系統(tǒng)被連接到互聯(lián)網對外提供服務)东且。
** docref_ext string**
參見 docref_root.
- Note:
docref_ext的值必須以 "." 開頭.
** error_prepend_string string**
錯誤信息之前輸出的內容。
** error_append_string string**
錯誤信息之后輸出的內容本讥。
** error_log string**
設置腳本錯誤將被記錄到的文件珊泳。該文件必須是web服務器用戶可寫的。如果特殊值 syslog 被設置拷沸,則將錯誤信息發(fā)送到系統(tǒng)日志記錄器色查。在Unix以及類似系統(tǒng)上,使用的是 syslog(3) 撞芍,而在 Windows NT 類系統(tǒng)上則為事件日志秧了。Windows 95上不支持系統(tǒng)日志記錄。參見: syslog(). 如果該配置沒有設置序无,則錯誤信息會被發(fā)送到 SAPI 錯誤記錄器验毡。例如,出現(xiàn)在Apache的錯誤日志中帝嗡,或者在CLI中發(fā)送到 stderr晶通。
預定義常量
值 常量 說明 備注
1 E_ERROR (integer) 致命的運行時錯誤。這類錯誤一般是不可恢復的情況哟玷,例如內存分配導致的問題狮辽。后果是導致腳本終止不再繼續(xù)運行。
2 E_WARNING (integer) 運行時警告 (非致命錯誤)巢寡。僅給出提示信息喉脖,但是腳本不會終止運行。
4 E_PARSE (integer) 編譯時語法解析錯誤抑月。解析錯誤僅僅由分析器產生树叽。
8 E_NOTICE (integer) 運行時通知。表示腳本遇到可能會表現(xiàn)為錯誤的情況谦絮,但是在可以正常運行的腳本里面也可能會有類似的通知题诵。
16 E_CORE_ERROR (integer) 在PHP初始化啟動過程中發(fā)生的致命錯誤须误。該錯誤類似 E_ERROR,但是是由PHP引擎核心產生的仇轻。 since PHP 4
32 E_CORE_WARNING (integer) PHP初始化啟動過程中發(fā)生的警告 (非致命錯誤) 京痢。類似 E_WARNING,但是是由PHP引擎核心產生的篷店。 since PHP 4
64 E_COMPILE_ERROR (integer) 致命編譯時錯誤祭椰。類似E_ERROR, 但是是由Zend腳本引擎產生的。 since PHP 4
128 E_COMPILE_WARNING (integer) 編譯時警告 (非致命錯誤)疲陕。類似 E_WARNING方淤,但是是由Zend腳本引擎產生的。 since PHP 4
256 E_USER_ERROR (integer) 用戶產生的錯誤信息蹄殃。類似 E_ERROR, 但是是由用戶自己在代碼中使用PHP函數(shù) trigger_error()來產生的携茂。 since PHP 4
512 E_USER_WARNING (integer) 用戶產生的警告信息。類似 E_WARNING, 但是是由用戶自己在代碼中使用PHP函數(shù) trigger_error()來產生的诅岩。 since PHP 4
1024 E_USER_NOTICE (integer) 用戶產生的通知信息讳苦。類似 E_NOTICE, 但是是由用戶自己在代碼中使用PHP函數(shù) trigger_error()來產生的。 since PHP 4
2048 E_STRICT (integer) 啟用 PHP 對代碼的修改建議吩谦,以確保代碼具有最佳的互操作性和向前兼容性鸳谜。 since PHP 5
4096 E_RECOVERABLE_ERROR (integer) 可被捕捉的致命錯誤。 它表示發(fā)生了一個可能非常危險的錯誤式廷,但是還沒有導致PHP引擎處于不穩(wěn)定的狀態(tài)咐扭。 如果該錯誤沒有被用戶自定義句柄捕獲 (參見 set_error_handler()),將成為一個 E_ERROR 從而腳本會終止運行滑废。 since PHP 5.2.0
8192 E_DEPRECATED (integer) 運行時通知蝗肪。啟用后將會對在未來版本中可能無法正常工作的代碼給出警告。 since PHP 5.3.0
16384 E_USER_DEPRECATED (integer) 用戶產少的警告信息蠕趁。 類似 E_DEPRECATED, 但是是由用戶自己在代碼中使用PHP函數(shù) trigger_error()來產生的薛闪。 since PHP 5.3.0
30719 E_ALL (integer) E_STRICT出外的所有錯誤和警告信息。 30719 in PHP 5.3.x, 6143 in PHP 5.2.x, 2047 previously
上面的值(數(shù)值或者符號)用于建立一個二進制位掩碼妻导,來制定要報告的錯誤信息逛绵。可以使用按位運算符來組合這些值或者屏蔽某些類型的錯誤倔韭。請注意,在 php.ini 之中瓢对,只有'|', '~', '!', '^' 和 '&' 會正確解析寿酌。
Example #1 在腳本中使用錯誤句柄**
<?php
// 我們將要定義自己的錯誤處理
error_reporting(0);
// 用戶自定義錯誤處理函數(shù)
function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars)
{
// 錯誤發(fā)生的時間
$dt = date("Y-m-d H:i:s (T)");
// 定義錯誤字符串的關聯(lián)數(shù)組
// 在這里我們只考慮
// E_WARNING, E_NOTICE, E_USER_ERROR,
// E_USER_WARNING 和 E_USER_NOTICE
$errortype = array (
E_ERROR => 'Error',
E_WARNING => 'Warning',
E_PARSE => 'Parsing Error',
E_NOTICE => 'Notice',
E_CORE_ERROR => 'Core Error',
E_CORE_WARNING => 'Core Warning',
E_COMPILE_ERROR => 'Compile Error',
E_COMPILE_WARNING => 'Compile Warning',
E_USER_ERROR => 'User Error',
E_USER_WARNING => 'User Warning',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Runtime Notice',
E_RECOVERABLE_ERROR => 'Catchable Fatal Error'
);
// 設置要保存變量跟蹤信息的錯誤類別
$user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);
$err = "<errorentry>\n";
$err .= "\t<datetime>" . $dt . "</datetime>\n";
$err .= "\t<errornum>" . $errno . "</errornum>\n";
$err .= "\t<errortype>" . $errortype[$errno] . "</errortype>\n";
$err .= "\t<errormsg>" . $errmsg . "</errormsg>\n";
$err .= "\t<scriptname>" . $filename . "</scriptname>\n";
$err .= "\t<scriptlinenum>" . $linenum . "</scriptlinenum>\n";
if (in_array($errno, $user_errors)) {
$err .= "\t<vartrace>" . wddx_serialize_value($vars, "Variables") . "</vartrace>\n";
}
$err .= "</errorentry>\n\n";
// for testing
// echo $err;
// 記錄錯誤信息到錯誤日志,并在發(fā)生關鍵用戶錯誤時發(fā)送電子郵件
error_log($err, 3, "/usr/local/php4/error.log");
if ($errno == E_USER_ERROR) {
mail("phpdev@example.com", "Critical User Error", $err);
}
}
function distance($vect1, $vect2)
{
if (!is_array($vect1) || !is_array($vect2)) {
trigger_error("Incorrect parameters, arrays expected", E_USER_ERROR);
return NULL;
}
if (count($vect1) != count($vect2)) {
trigger_error("Vectors need to be of the same size", E_USER_ERROR);
return NULL;
}
for ($i=0; $i<count($vect1); $i++) {
$c1 = $vect1[$i]; $c2 = $vect2[$i];
$d = 0.0;
if (!is_numeric($c1)) {
trigger_error("Coordinate $i in vector 1 is not a number, using zero",
E_USER_WARNING);
$c1 = 0.0;
}
if (!is_numeric($c2)) {
trigger_error("Coordinate $i in vector 2 is not a number, using zero",
E_USER_WARNING);
$c2 = 0.0;
}
$d += $c2*$c2 - $c1*$c1;
}
return sqrt($d);
}
$old_error_handler = set_error_handler("userErrorHandler");
// 未定義的常量硕蛹,將產生一個警告
$t = I_AM_NOT_DEFINED;
// 定義一些 "載體"
$a = array(2, 3, "foo");
$b = array(5.5, 4.3, -1.6);
$c = array(1, -3);
// 引發(fā)一個用戶錯誤
$t1 = distance($c, $b) . "\n";
// 再次引發(fā)一個用戶錯誤
$t2 = distance($b, "i am not an array") . "\n";
// 引發(fā)一個警告
$t3 = distance($a, $b) . "\n";
?>
錯誤處理 函數(shù)
- debug_backtrace — 產生一條回溯跟蹤(backtrace)
- debug_print_backtrace — 打印一條回溯醇疼。
- error_clear_last — Clear the most recent error
- error_get_last — 獲取最后發(fā)生的錯誤
- error_log — 發(fā)送錯誤信息到某個地方
- error_reporting — 設置應該報告何種 PHP 錯誤
- restore_error_handler — 還原之前的錯誤處理函數(shù)
- restore_exception_handler — 恢復之前定義過的異常處理函數(shù)硕并。
- set_error_handler — 設置一個用戶定義的錯誤處理函數(shù)
- set_exception_handler — 設置一個用戶定義的異常處理函數(shù)。
- trigger_error — 產生一個用戶級別的 error/warning/notice 信息
- user_error — trigger_error 的別名