簡(jiǎn)介
PHP提供了錯(cuò)誤處理和日志記錄的功能. 這些函數(shù)允許你定義自己的錯(cuò)誤處理規(guī)則,以及修改錯(cuò)誤記錄的方式. 這樣,你就可以根據(jù)自己的需要,來(lái)更改和加強(qiáng)錯(cuò)誤輸出信息以滿足實(shí)際需要.
通過日志記錄功能,你可以將信息直接發(fā)送到其他日志服務(wù)器,或者發(fā)送到指定的電子郵箱(或者通過郵件網(wǎng)關(guān)發(fā)送),或者發(fā)送到操作系統(tǒng)日志等,從而可以有選擇的記錄和監(jiān)視你的應(yīng)用程序和網(wǎng)站的最重要的部分。
錯(cuò)誤報(bào)告功能允許你自定義錯(cuò)誤反饋的級(jí)別和類型,可以是簡(jiǎn)單的提示信息或者使用自定義的函數(shù)進(jìn)行處理并返回信息.
運(yùn)行時(shí)配置
這些函數(shù)的行為受 php.ini 中的設(shè)置影響。
** error_reporting integer**
設(shè)置錯(cuò)誤報(bào)告的級(jí)別。該參數(shù)可以是一個(gè)任意的表示二進(jìn)制位字段的整數(shù),或者常數(shù)名稱。錯(cuò)誤級(jí)別和常數(shù)是在 預(yù)定義常量定義的,在 php.ini 之中也有專門的說明。在程序運(yùn)行時(shí),還可以通過 error_reporting() 函數(shù)進(jìn)行設(shè)置。請(qǐng)查看 display_errors 了解詳情。
在PHP 4和PHP 5之中,其默認(rèn)值為 E_ALL & ~E_NOTICE。 該設(shè)置表示除了 E_NOTICE 其他都顯示的錯(cuò)誤級(jí)別。在開發(fā)過程中很有必要顯示它們。
Note:
在開發(fā)階段啟用 E_NOTICE 會(huì)有一些好處。出于調(diào)試的目的:通知信息會(huì)對(duì)代碼中可能出現(xiàn)的bug給出警告。例如,使用未預(yù)先分配和定義的值,就會(huì)給出警告。它對(duì)于查找拼寫錯(cuò)誤非常有用,并且可以節(jié)省調(diào)試的時(shí)間。通知信息也會(huì)警告你使用更好的代碼風(fēng)格。例如,$arr[item] 最好寫成 $arr['item'] ,因?yàn)?PHP 會(huì)試圖將 "item" 當(dāng)成一個(gè)常量。如果它不是一個(gè)常量,PHP才會(huì)把它當(dāng)做數(shù)組的字符串索引。
Note:
在PHP 5之中,提供了一個(gè)新的錯(cuò)誤級(jí)別 E_STRICT。 因?yàn)?E_STRICT 并不包含在 E_ALL 之中,你必須明確啟用才能顯示這個(gè)類別的錯(cuò)誤信息。在開發(fā)階段啟用 E_STRICT 會(huì)有一些好處。嚴(yán)格的信息將幫助你使用最新和最好的建議的方法來(lái)編寫代碼,例如它會(huì)警告你使用了將被廢棄的函數(shù)。
Note: PHP外的PHP常量
在 PHP 以外使用PHP的常量是沒有意義的,例如在 httpd.conf 之中, 你需要使用常量對(duì)應(yīng)的 integer 值來(lái)取代。因?yàn)殡S著時(shí)間的推移和PHP的發(fā)展,會(huì)有更多的錯(cuò)誤級(jí)別將被添加,因此錯(cuò)誤級(jí)別的最大值(為 E_ALL)可能會(huì)改變 。因此在使用 E_ALL 對(duì)應(yīng)整數(shù)值的地方,應(yīng)該考慮使用較大的數(shù)值來(lái)涵蓋當(dāng)前和將來(lái)需要使用的二進(jìn)制位字段,例如數(shù)值 2147483647 (將包含所有錯(cuò)誤,而不僅僅是 E_ALL).
** display_errors string**
該選項(xiàng)設(shè)置是否將錯(cuò)誤信息作為輸出的一部分顯示到屏幕,或者對(duì)用戶隱藏而不顯示。
設(shè)置 "stderr" 表示發(fā)送到 stderr 而不是 stdout。 "stderr"從 PHP 5.2.4 開始可用。在以前的版本中,該配置值的類型為 boolean.
Note:
這是一個(gè)輔助開發(fā)的功能,建議永遠(yuǎn)不要在生產(chǎn)系統(tǒng)中使用 (例如系統(tǒng)被連接到互聯(lián)網(wǎng)對(duì)外提供服務(wù))。Note:
盡管 display_errors 也可以在運(yùn)行時(shí)設(shè)置 (使用 ini_set()), 但是腳本出現(xiàn)致命錯(cuò)誤時(shí)任何運(yùn)行時(shí)的設(shè)置都是無(wú)效的。 因?yàn)樵谶@種情況下預(yù)期運(yùn)行的操作不會(huì)被執(zhí)行。
** display_startup_errors boolean**
即使 display_errors 設(shè)置為開啟, PHP 啟動(dòng)過程中的錯(cuò)誤信息也不會(huì)被顯示。強(qiáng)烈建議除了調(diào)試目的以外,將 display_startup_errors 設(shè)置為關(guān)閉。
** log_errors boolean**
設(shè)置是否將腳本運(yùn)行的錯(cuò)誤信息記錄到服務(wù)器錯(cuò)誤日志或者error_log之中。注意,這是與服務(wù)器相關(guān)的特定配置項(xiàng)。
Note:
在生產(chǎn)系統(tǒng)中,強(qiáng)烈建議你使用錯(cuò)誤日志記錄web站點(diǎn)上顯示的錯(cuò)誤信息。
** log_errors_max_len integer**
設(shè)置 log_errors 的最大字節(jié)數(shù). 在 error_log 會(huì)添加有關(guān)錯(cuò)誤源的信息。默認(rèn)值為1024,如果設(shè)置為0表示不限長(zhǎng)度。該長(zhǎng)度設(shè)置對(duì)記錄的錯(cuò)誤,顯示的錯(cuò)誤,以及 $php_errormsg都會(huì)有限制作用。
當(dāng)使用 integer 時(shí), 其值以字節(jié)來(lái)衡量。還可以使用在FAQ中描述的速記符。
** ignore_repeated_errors boolean**
不記錄重復(fù)的信息。重復(fù)的錯(cuò)誤必須出現(xiàn)在同一個(gè)文件中的同一行代碼上,除非 ignore_repeated_source 設(shè)置為true。
** ignore_repeated_source boolean**
忽略重復(fù)消息時(shí),也忽略消息的來(lái)源。當(dāng)該設(shè)置開啟時(shí),重復(fù)信息將不會(huì)記錄它是由不同的文件還是不同的源代碼行產(chǎn)生的。
** report_memleaks boolean**
如果這個(gè)參數(shù)設(shè)置為Off,則內(nèi)存泄露信息不會(huì)顯示 (在 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。這只對(duì)調(diào)試編譯有效,而且需要 error_reporting 包含了 E_WARNING 才會(huì)起作用
** track_errors boolean**
如果開啟,最后的一個(gè)錯(cuò)誤將永遠(yuǎn)存在于變量 $php_errormsg 中。
** html_errors boolean**
在錯(cuò)誤信息中關(guān)閉HTML標(biāo)簽。這種新的HTML格式的錯(cuò)誤信息是可以點(diǎn)擊,它引導(dǎo)用戶前往描述該錯(cuò)誤或者導(dǎo)致該錯(cuò)誤發(fā)生的函數(shù)的參考信息頁(yè)面。 這些參考與 docref_root 和 docref_ext 的設(shè)置有關(guān)。
** xmlrpc_errors boolean**
關(guān)閉正常的錯(cuò)誤報(bào)告,并將錯(cuò)誤的格式設(shè)置為XML-RPC錯(cuò)誤信息的格式。
** xmlrpc_error_number integer**
用作 XML-RPC faultCode 元素的值。
** docref_root string**
新的錯(cuò)誤信息格式包含了對(duì)應(yīng)的參考頁(yè)面,該頁(yè)面對(duì)錯(cuò)誤進(jìn)行具體描述,或者描述了導(dǎo)致該錯(cuò)誤發(fā)生的函數(shù)。為了提供手冊(cè)的頁(yè)面,你可以在PHP官方站點(diǎn)下載對(duì)應(yīng)語(yǔ)言的手冊(cè),并在ini中設(shè)置網(wǎng)址到本地對(duì)應(yīng)的地址。如果你的本地手冊(cè)拷貝可以使用"/manual/" 訪問,你就可以簡(jiǎn)單的設(shè)置 docref_root=/manual/。另外你還需要設(shè)置 docref_ext 匹配你本地文件的后綴名 docref_ext=.html。當(dāng)然也可以設(shè)置一個(gè)外部的參考地址。例如你可以設(shè)置 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 后面以 "/"結(jié)尾, 但是在以上的第二種示例情況中不必這么設(shè)置。
- Note:
因?yàn)檫@么做可以快速定位和查看到函數(shù)的說明,所以它對(duì)你的開發(fā)會(huì)非常有用。建議永遠(yuǎn)不要再生產(chǎn)系統(tǒng)中使用 (例如系統(tǒng)被連接到互聯(lián)網(wǎng)對(duì)外提供服務(wù))。
** docref_ext string**
參見 docref_root.
- Note:
docref_ext的值必須以 "." 開頭.
** error_prepend_string string**
錯(cuò)誤信息之前輸出的內(nèi)容。
** error_append_string string**
錯(cuò)誤信息之后輸出的內(nèi)容。
** error_log string**
設(shè)置腳本錯(cuò)誤將被記錄到的文件。該文件必須是web服務(wù)器用戶可寫的。如果特殊值 syslog 被設(shè)置,則將錯(cuò)誤信息發(fā)送到系統(tǒng)日志記錄器。在Unix以及類似系統(tǒng)上,使用的是 syslog(3) ,而在 Windows NT 類系統(tǒng)上則為事件日志。Windows 95上不支持系統(tǒng)日志記錄。參見: syslog(). 如果該配置沒有設(shè)置,則錯(cuò)誤信息會(huì)被發(fā)送到 SAPI 錯(cuò)誤記錄器。例如,出現(xiàn)在Apache的錯(cuò)誤日志中,或者在CLI中發(fā)送到 stderr。
預(yù)定義常量
值 常量 說明 備注
1 E_ERROR (integer) 致命的運(yùn)行時(shí)錯(cuò)誤。這類錯(cuò)誤一般是不可恢復(fù)的情況,例如內(nèi)存分配導(dǎo)致的問題。后果是導(dǎo)致腳本終止不再繼續(xù)運(yùn)行。
2 E_WARNING (integer) 運(yùn)行時(shí)警告 (非致命錯(cuò)誤)。僅給出提示信息,但是腳本不會(huì)終止運(yùn)行。
4 E_PARSE (integer) 編譯時(shí)語(yǔ)法解析錯(cuò)誤。解析錯(cuò)誤僅僅由分析器產(chǎn)生。
8 E_NOTICE (integer) 運(yùn)行時(shí)通知。表示腳本遇到可能會(huì)表現(xiàn)為錯(cuò)誤的情況,但是在可以正常運(yùn)行的腳本里面也可能會(huì)有類似的通知。
16 E_CORE_ERROR (integer) 在PHP初始化啟動(dòng)過程中發(fā)生的致命錯(cuò)誤。該錯(cuò)誤類似 E_ERROR,但是是由PHP引擎核心產(chǎn)生的。 since PHP 4
32 E_CORE_WARNING (integer) PHP初始化啟動(dòng)過程中發(fā)生的警告 (非致命錯(cuò)誤) 。類似 E_WARNING,但是是由PHP引擎核心產(chǎn)生的。 since PHP 4
64 E_COMPILE_ERROR (integer) 致命編譯時(shí)錯(cuò)誤。類似E_ERROR, 但是是由Zend腳本引擎產(chǎn)生的。 since PHP 4
128 E_COMPILE_WARNING (integer) 編譯時(shí)警告 (非致命錯(cuò)誤)。類似 E_WARNING,但是是由Zend腳本引擎產(chǎn)生的。 since PHP 4
256 E_USER_ERROR (integer) 用戶產(chǎn)生的錯(cuò)誤信息。類似 E_ERROR, 但是是由用戶自己在代碼中使用PHP函數(shù) trigger_error()來(lái)產(chǎn)生的。 since PHP 4
512 E_USER_WARNING (integer) 用戶產(chǎn)生的警告信息。類似 E_WARNING, 但是是由用戶自己在代碼中使用PHP函數(shù) trigger_error()來(lái)產(chǎn)生的。 since PHP 4
1024 E_USER_NOTICE (integer) 用戶產(chǎn)生的通知信息。類似 E_NOTICE, 但是是由用戶自己在代碼中使用PHP函數(shù) trigger_error()來(lái)產(chǎn)生的。 since PHP 4
2048 E_STRICT (integer) 啟用 PHP 對(duì)代碼的修改建議,以確保代碼具有最佳的互操作性和向前兼容性。 since PHP 5
4096 E_RECOVERABLE_ERROR (integer) 可被捕捉的致命錯(cuò)誤。 它表示發(fā)生了一個(gè)可能非常危險(xiǎn)的錯(cuò)誤,但是還沒有導(dǎo)致PHP引擎處于不穩(wěn)定的狀態(tài)。 如果該錯(cuò)誤沒有被用戶自定義句柄捕獲 (參見 set_error_handler()),將成為一個(gè) E_ERROR 從而腳本會(huì)終止運(yùn)行。 since PHP 5.2.0
8192 E_DEPRECATED (integer) 運(yùn)行時(shí)通知。啟用后將會(huì)對(duì)在未來(lái)版本中可能無(wú)法正常工作的代碼給出警告。 since PHP 5.3.0
16384 E_USER_DEPRECATED (integer) 用戶產(chǎn)少的警告信息。 類似 E_DEPRECATED, 但是是由用戶自己在代碼中使用PHP函數(shù) trigger_error()來(lái)產(chǎn)生的。 since PHP 5.3.0
30719 E_ALL (integer) E_STRICT出外的所有錯(cuò)誤和警告信息。 30719 in PHP 5.3.x, 6143 in PHP 5.2.x, 2047 previously
上面的值(數(shù)值或者符號(hào))用于建立一個(gè)二進(jìn)制位掩碼,來(lái)制定要報(bào)告的錯(cuò)誤信息。可以使用按位運(yùn)算符來(lái)組合這些值或者屏蔽某些類型的錯(cuò)誤。請(qǐng)注意,在 php.ini 之中,只有'|', '~', '!', '^' 和 '&' 會(huì)正確解析。
Example #1 在腳本中使用錯(cuò)誤句柄**
<?php
// 我們將要定義自己的錯(cuò)誤處理
error_reporting(0);
// 用戶自定義錯(cuò)誤處理函數(shù)
function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars)
{
// 錯(cuò)誤發(fā)生的時(shí)間
$dt = date("Y-m-d H:i:s (T)");
// 定義錯(cuò)誤字符串的關(guān)聯(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'
);
// 設(shè)置要保存變量跟蹤信息的錯(cuò)誤類別
$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;
// 記錄錯(cuò)誤信息到錯(cuò)誤日志,并在發(fā)生關(guān)鍵用戶錯(cuò)誤時(shí)發(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");
// 未定義的常量,將產(chǎn)生一個(gè)警告
$t = I_AM_NOT_DEFINED;
// 定義一些 "載體"
$a = array(2, 3, "foo");
$b = array(5.5, 4.3, -1.6);
$c = array(1, -3);
// 引發(fā)一個(gè)用戶錯(cuò)誤
$t1 = distance($c, $b) . "\n";
// 再次引發(fā)一個(gè)用戶錯(cuò)誤
$t2 = distance($b, "i am not an array") . "\n";
// 引發(fā)一個(gè)警告
$t3 = distance($a, $b) . "\n";
?>
錯(cuò)誤處理 函數(shù)
- debug_backtrace — 產(chǎn)生一條回溯跟蹤(backtrace)
- debug_print_backtrace — 打印一條回溯。
- error_clear_last — Clear the most recent error
- error_get_last — 獲取最后發(fā)生的錯(cuò)誤
- error_log — 發(fā)送錯(cuò)誤信息到某個(gè)地方
- error_reporting — 設(shè)置應(yīng)該報(bào)告何種 PHP 錯(cuò)誤
- restore_error_handler — 還原之前的錯(cuò)誤處理函數(shù)
- restore_exception_handler — 恢復(fù)之前定義過的異常處理函數(shù)。
- set_error_handler — 設(shè)置一個(gè)用戶定義的錯(cuò)誤處理函數(shù)
- set_exception_handler — 設(shè)置一個(gè)用戶定義的異常處理函數(shù)。
- trigger_error — 產(chǎn)生一個(gè)用戶級(jí)別的 error/warning/notice 信息
- user_error — trigger_error 的別名