3.PHP自訂錯誤處理器

來源:互聯網
上載者:User

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()等終止函數

    著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.