利用PHP自訂錯誤處理器處理出錯資訊

來源:互聯網
上載者:User
如果您是PHP老手,當然知道當PHP指令碼出錯時發生了什麼事情。此時PHP解析器將在螢幕上給出錯誤資訊,如 Fatal error: Call to undefined function on line 19 --,因此程式在此處終止。這個資訊會嚇到客戶,他可能立即打電話和你進行諮詢。

幸運的是,這裡有解決辦法。PHP擁有內建工具,可以讓開發人員捕捉指令碼錯誤然後將它們轉到自訂的錯誤處理器。此時則可以對處理器進行編程顯示更多關於錯誤的詳細資料。還可以將錯誤寫入檔案或資料庫以採取補救措施。有時候還可以對處理器編寫程式忽略錯誤訊息。

本文中,我將闡述如何使用PHP的錯誤處理API構建使用者自訂的錯誤處理器,並且說明如何以簡單而友好的方式顯示和管理指令碼的錯誤資訊。

錯誤類型和報告層級

我們從最基本的開始。PHP有三種最基本的錯誤類型,從低級到進階分別為:注意、警告和錯誤(或致命錯誤)。通常情況下,注意和警告不會終止程式;但是致命錯誤則是危險故障(例如,調用一個沒有定義的函數或參考一個不存在的對象),將導致程式中斷。這些錯誤有可能在啟動、解析、編譯或運行時發生。

關鍵字如E_NOTICE, E_ERROR等用於表明錯誤的不同類型和等級。在PHP手冊上可以獲得它們的詳細資料列表。

指令碼階段錯誤顯示由error_reporting()函數進行控制。這一函數針對不同的錯誤等級設定不同的參數。表A給出了使用此函數報警示告和致命錯誤的指令碼程式。

表A

// display warnings and errors

error_reporting(E_WARNING E_ERROR);

// this will generate a notice, which will never be displayed

echo $undefinedVar;

// this will generate a fatal error, which will be displayed

callUndefFunc();

?>

將表B中的代碼與上面的進行比較發現,Listing B中隱藏錯誤資訊甚至隱藏致命資訊,使得錯誤資訊不會被顯示出來。

表B

// turn off error display

// no errors will be displayed

error_reporting(0);

// this will generate a notice

echo $undefinedVar;

// this will generate a fatal error

callUndefFunc();

?>

表C中的代碼將所有錯誤資訊甚至簡單的注意事項都顯示出來:

表C

// all errors will be displayed

error_reporting(E_ALL);

// this will generate a notice

echo $undefinedVar;

// this will generate a fatal error

callUndefFunc();

?>

如以上3個例子所示,error_reporting()函數在控制錯誤發生時,在螢幕上顯示內容非常重要。這裡的關鍵字是displayed,其表達的意思是錯誤不被顯示而不是錯誤沒有發生。因此,發生致命錯誤時(例如不正確的函數調用),程式將被終止;但是,此時沒有任何訊息顯示給使用者。

下面的例子(表 D)說明了這種情況:

表D

// no errors will be displayed

error_reporting(0);

// start a task

echo "Starting task...";

// call an undefined function

// a fatal error occurs during task processing

callMe();

// end the task

echo "Successfully completed task...";

?>

在表D中,在調用echo()函數時發生了致命錯誤,程式執行時到這點被終止,但是卻沒有任何錯誤訊息給出,使用者不知道這種情況還以為程式在正確運行。下面的結論是非常明顯的:不給出錯誤報表非常危險,因為不論過程是否完成它常導致不正確的結論。

注意:調用不帶任何參數的error_reporting()將返回當前的錯誤報表等級。

自訂錯誤處理器

很明顯,隱藏錯誤報表是不正確的,你肯定想知道有什麼其他辦法加以改進。自訂錯誤處理器就是一個很好的能取代PHP預設錯誤處理系統的解決方案。自訂錯誤處理器可以以任何方式設定處理錯誤資訊,包括資訊如何顯示。

PHP函數中,完成這一功能的是set_error_handler()函數。錯誤發生時,此函數被自動調用,然後給出4個參數:錯誤碼、錯誤訊息、發生錯誤的指令碼名稱和錯誤出現的行,此函數對錯誤管理負責。

表E給出一個簡單例子:

表E

// define custom handler

set_error_handler('myHandler');

// custom handler code

function myHandler($code, $msg, $file, $line) {

echo "Just so you know, something went wrong at line $line of your script $file. The system says that the error code was $code, and the reason for the error was: $msg. Sorry about this!";

}

// generate a notice

echo $undefVar;

?>

當運行此指令碼的時候,會出現下面的資訊:

Just so you know, something went wrong at line 11 of your /dev/error1.php. The system says that the error code was 8, and the reason for the error was: Undefined variable: undefVar. Sorry about this!

此時,PHP的預設錯誤處理器被使用者定義的myHandler()函數所取代,$undefVar變數被啟用,PHP通知未定義變數的資訊,此資訊在運行時引擎產生,然後傳遞給myHandler()函數,同時錯誤發生的地址也傳遞給此函數。然後myHandler()函數輸出友好資訊解釋錯誤。

注意:錯誤和致命錯誤很重要,它們會繞過自訂錯誤處理器,然後以PHP預設的錯誤處理機制進行顯示。顯示這些資訊可使用前面討論的標準error_reporting()函數進行控制。

例1:動態錯誤頁面和e-mail警報

表F給出了另一個範例,當發生錯誤時,將動態產生HTML錯誤頁面,並且通過e-mail向Web管理員進行報告。

表F

// define custom handler

set_error_handler('myHandler');

// custom handler code

function myHandler($code, $msg, $file, $line, $context) {

// print error page

echo "";

echo "

Error!

";

echo "";

echo "An error occurred while processing your request. Please visit our home page and try again.";

echo "";

echo "";

// email error to admin

$body = "$msg at $file ($line), timed at " . date ("d-M-Y h:i:s", mktime());

$body .= "\n\n" . print_r($context, TRUE);

mail ("webmaster@domain.dom", "Web site error", $body);

// halt execution of script

die();

}

// generate a notice

echo $undefVar;

?>

這裡,自訂的錯誤處理器在遇到錯誤時動態產生HTML錯誤頁面。此錯誤資訊也能被e-mail資訊捕獲,然後通過PHP內建的mail()函數發送給管理員。

這裡出現了myHandler()函數的一個新參數$context。這是myHandler()函數的第五個參數,是可選項。它包含了當前變數狀態的快照。包括對管理員有用的上下文資訊,有利於減少調試時間。

例2:自訂錯誤記錄檔

表G給出了另一個例子,這個例子說明自訂錯誤處理器如何將詳細的錯誤資訊輸入到檔案。

表G

// define custom handler

set_error_handler('myHandler');

// custom handler code

function myHandler($code, $msg, $file, $line) {

// print error page

echo "";

echo "

Error!

";

echo "";

echo "An error occurred while processing your request. Please visit our home page and try again.";

echo "";

echo "";

// log error to file, with context

$logData = date("d-M-Y h:i:s", mktime()) . ", $code, $msg, $line, $file\n";

file_put_contents("web.log", $logData, FILE_APPEND);

// halt execution of script

die();

}

// generate a warning

echo is_float();

?>

與前面的例子相似,它也產生一個錯誤頁面並且將錯誤資料輸入到檔案,以利於管理員進行查看。資料以CSV格式進行儲存,並且有簡單的資料分析和報告。請注意在本例和前面執行個體中,錯誤處理代碼結束時調用die()函數,以確保指令碼不再運行。

如上面的範例所示,自訂錯誤處理器允許以友好的方式處理PHP指令碼錯誤。並且可以發揮自己的創造性,不過需要記住的是:任何靈活性的增加都伴隨著開銷和時間的增加。



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.