1. 使用set_error_handler 自訂錯誤處理函數說明
1.建立錯誤處理函數
2.設定不同層級調用函數
3.set_error_handler函數指定接管錯誤處理
set_error_handler 說明
mixed set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )設定一個使用者的函數(error_handler)來處理指令碼中出現的錯誤。本函數可以用你自己定義的方式來處理運行中的錯誤, 例如,在應用程式中嚴重錯誤發生時,或者在特定條件下觸發了一個錯誤(使用 trigger_error()),你需要對資料/檔案做清理回收。重要的是要記住 error_types 裡指定的錯誤類型都會繞過 PHP 標準錯誤處理常式, 除非回呼函數返回了 FALSE。 error_reporting() 設定將不會起到作用而你的錯誤處理函數繼續會被調用 ?? 不過你仍然可以擷取 error_reporting 的當前值,並做適當處理。 需要特別注意的是帶 @ error-control operator 首碼的語句發生錯誤時,這個值會是 0。同時注意,在需要時你有責任使用 die()。 如果錯誤處理程式返回了,指令碼將會繼續執行發生錯誤的後一行。以下層級的錯誤不能由使用者定義的函數來處理: E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING,和在 調用 set_error_handler() 函數所在檔案中產生的大多數 E_STRICT。如果錯誤發生在指令碼執行之前(比如檔案上傳時),將不會 調用自訂的錯誤處理程式因為它尚未在那時註冊。參數error_handler使用者的函數需要接受兩個參數:錯誤碼和描述錯誤的 string。 另外有可能提供三個選擇性參數:發生錯誤的檔案名稱、發生錯誤的行號 以及發生錯誤的上下文(一個指向錯誤發生時活動符號表的 array)。 該函數可以表示為:handler ( int $errno , string $errstr [, string $errfile [, int $errline [, array $errcontext ]]] )errno第一個參數 errno,包含了錯誤的層級,是一個 integer。errstr第二個參數 errstr,包含了錯誤的資訊,是一個 string。errfile第三個參數是可選的,errfile, 包含了發生錯誤的檔案名稱,是一個 string。errline第四個參數是一個可選項, errline, 包含了錯誤發生的行號,是一個 integer。errcontext第五個選擇性參數, errcontext, 是一個指向錯誤發生時活動符號表的 array。 也就是說,errcontext 會包含錯誤觸發處範圍內所有變數的數組。 使用者的錯誤處理程式不應該修改錯誤上下文(context)。如果函數返回 FALSE,標準錯誤處理處理常式將會繼續調用。error_types就像error_reporting 的 ini 設定能夠控制錯誤的顯示一樣, 此參數能夠用於屏蔽 error_handler 的觸發。 如果沒有該掩碼, 無論 error_reporting 是如何設定的, error_handler 都會在每個錯誤發生時被調用。
2. set_error_handler的使用
header('content-type:text/html; charset=utf-8');//開啟所有的錯誤報表error_reporting(-1);function customError($errno, $errmsg, $errfile, $errline){ if (!(error_reporting() & $errno)) { // This error code is not included in error_reporting return; } switch ($errno) { case E_USER_ERROR: echo "My ERROR [$errno] $errmsg
".PHP_EOL; echo " Fatal error on line $errline in file $errfile"; echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")
".PHP_EOL; echo "Aborting...
\n"; // exit(1); break; case E_USER_WARNING: echo "My WARNING [$errno] $errmsg
".PHP_EOL; break; case E_USER_NOTICE: echo "My NOTICE [$errno] $errmsg
".PHP_EOL; break; default: echo "Unknown error type: [$errno] $errmsg
".PHP_EOL; break; } /* Don't execute PHP internal error handler */ return true;}set_error_handler('customError');echo $test;settype($var, 'king');// test();trigger_error('出錯了!', E_USER_ERROR);echo '';//回收錯誤接管restore_error_handler();echo $king;echo '';set_error_handler('customError', E_ALL&~E_NOTICE);echo '';settype($var, 'king');echo 'continue...............';
3.自訂錯誤處理類
/** * 自訂錯誤處理類 */class MyErrorHandler { public $msg=''; public $filename=''; public $line=0; public $vars=array(); protected $_noticeLog = '/tmp/php_error.log'; function __construct($msg, $filename, $line, $vars) { $this->msg=$msg; $this->filename=$filename; $this->line=$line; $this->vars=$vars; } /** * [deal 自訂錯誤處理請求] * @param [int] $errno [錯誤號碼] * @param [string] $errmsg [錯誤描述] * @param [string] $errfile [出錯的檔案] * @param [int] $errline [出錯的行號] * @param [array] $vars [錯誤觸發處範圍內所有變數的數組] * @return [bool] */ public static function deal($errno, $errmsg, $errfile, $errline, $vars){ $self = new self($errmsg, $errfile, $errline, $vars); switch ($errno) { //致命層級的錯誤發郵件給管理員 case E_USER_ERROR: return $self->dealError(); break; case E_USER_WARNING: case E_WARNING: return $self->dealWarning(); break; case E_USER_NOTICE: case E_NOTICE: return $self->dealNotice(); break; default: //交給php本身的錯誤機制處理 return false; break; } } public function get_debug_print_backtrace($traces_to_ignore = 1){ $traces = debug_backtrace(); $ret = array(); foreach($traces as $i => $call){ if ($i < $traces_to_ignore ) { continue; } $object = ''; if (isset($call['class'])) { $object = $call['class'].$call['type']; if (is_array($call['args'])) { foreach ($call['args'] as &$arg) { $this->get_arg($arg); } } } $ret[] = '#'.str_pad($i - $traces_to_ignore, 3, ' ') .$object.$call['function'].'('.implode(', ', $call['args']) .') called at ['.$call['file'].':'.$call['line'].']'; } return implode("\n",$ret); } public function get_arg(&$arg) { if (is_object($arg)) { $arr = (array)$arg; $args = array(); foreach($arr as $key => $value) { if (strpos($key, chr(0)) !== false) { $key = ''; // Private variable found } $args[] = '['.$key.'] => '.get_arg($value); } $arg = get_class($arg) . ' Object ('.implode(',', $args).')'; } } /** * [dealError 處理錯誤層級的錯誤] * @return [type] [description] */ public function dealError(){ $backtrace=$this->get_debug_print_backtrace(); echo $backtrace; exit; $errorMsg=<<filename} 產生錯誤的資訊:{$this->msg} 產生錯誤的行號:{$this->line} 追蹤資訊:{$backtrace} \n EOF; error_log($errorMsg, 1, '732578448@qq.com'); exit(1); } /** * [dealWarning 處理警告層級的錯誤] * @return [bool] */ public function dealWarning(){ $errorMsg=<<filename} 產生警告的資訊:{$this->msg} 產生警告的行號:{$this->line} \n EOF; error_log($errorMsg, 1, '732578448@qq.com'); } /** * [dealNotice 處理通知層級的錯誤] * @return bool */ public function dealNotice(){ $datetime = date('Y-m-d H:i:s', time()); $errorMsg=<<filename} 產生通知的資訊:{$this->msg} 產生通知的行號:{$this->line} 產生通知的時間:{$datetime} \n EOF; return error_log($errorMsg, 3, $this->_noticeLog); }}error_reporting(-1);set_error_handler(array('MyErrorHandler', 'deal'));ini_set('display_errors', 0);echo $var;trigger_error('zhiming', E_USER_ERROR);trigger_error('zhiming', E_USER_WARNING);
4.register_shutdown_function函數的使用
1.作用
1.通過register_shutdown_function函數,可以讓我們設定一個當執行關閉時可以被調用的另一個函數。
2.當我們的指令碼執行完成或意外死掉導致PHP執行即將關閉時,我們的這個函數將會被調用
2.使用情境
1.頁面強制被停止
2.程式碼意外終止或逾時
3.注意點
1.在register_shutdown_function之前不能有die() exit()等終止函數
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。