2013-02-08 67 views
8

處理在我的工程來抓我已經建立了我的錯誤處理機制上的所有PHP錯誤如下:錯誤笨

  1. 我在index.php文件,該文件將覆蓋php.ini文件 任何設置error_reporting()
  2. 錯誤處理程序使用 set_error_handlersystem/codeigniter/CodeIgniter.php設置 - 這個錯誤處理程序,_exception_handler,是 在system/codeigniter/Common.php
  3. 的發現函數忽略E_STRICT錯誤,如果是,你error_reporting()功能 index.php指定的 嚴重性調用 show_php_error功能從異常系統庫和記錄錯誤根據不管你已經在你的config.php文件
  4. 的處理程序中設置返回FALSE,所以在這個PHP繼續處理 錯誤但是它通常會根據您的error_reporting級別 和display_errors設置。

讓我感到困惑的是E_ERROR錯誤,即致命錯誤似乎沒有被_exception_handler捕獲。這不僅僅是show_php_error沒有被調用,它看起來像函數沒有被調用。這顯然是一個問題,因爲這意味着它們不會被show_php_error處理或記錄。例如,如果我故意在控制器中輸入$this->load->views('foo');,處理程序不會被調用。

任何有關錯誤處理的建議將不勝感激,謝謝!

+0

我認爲這可能是PHP本身無法測試它的問題。如果您看到http://www.php.net/manual/en/function.error-reporting。php#70126你會發現在這種情況下,E_ERROR會導致類似於E_PARSE會做的事情。 – David 2013-02-10 23:36:43

+0

你在用什麼環境? – bottleboot 2013-02-15 15:35:36

回答

4

現在這是一個相當大的辯論: 是否應該抓住致命錯誤。有些人說他們是致命的,所以你不知道在哪個條件下系統,但我會與「嘗試做清理,如果錯誤發生」。 爲了捕獲所有致命錯誤,您需要設置pre_system鉤子。 去的application/config/hooks.php並進入

$hook['pre_system'][] = array(
'class' => 'PHPFatalError', 
'function' => 'setHandler', 
'filename' => 'PHPFatalError.php', 
'filepath' => 'hooks' 
); 

後去鉤目錄,並添加錯誤處理您:

<?php 
    class PHPFatalError { 

    public function setHandler() { 
      register_shutdown_function('handleShutdown'); 
     } 

    } 

    function handleShutdown() { 
     if (($error = error_get_last())) { 
      ob_start(); 
       echo "<pre>"; 
      var_dump($error); 
       echo "</pre>"; 
      $message = ob_get_clean(); 
      sendEmail($message); 
      ob_start(); 
      echo '{"status":"error","message":"Internal application error!"}'; 
      ob_flush(); 
      exit(); 
     } 
    } 

,你可以看到,我們正在使用的register_shutdown_function到運行一個函數,檢查是否發生了錯誤,以及是否通過電子郵件將其發送給開發人員。 這個設置在我一直與之合作的幾個CI項目中工作了兩年多,完美無缺。

+0

TIX嗨,我覺得這是真正的好方法,但在我的情況我已經開發了一個定製的方法,在那裏我有register_shutdown_function()來在一個輔助類來處理項目的整體錯誤...謝謝你 – troy 2013-02-16 10:44:54

+0

那麼你最多可以疊加register_shutdown_function()但沒有其他方式(據我所知),除了使用預處理系統鉤子之外,您可以捕獲致命錯誤。 – tix3 2013-02-17 16:12:29

0

我在其他問題(https://stackoverflow.com/a/3675357)中發現了這個答案,我認爲這對任何閱讀此問題的人都很有用。 「 」對於codeigniter特定的錯誤處理,您可以通過在應用程序/庫文件夾中創建My_Exception類來覆蓋它的'Exception'庫類。將原始庫函數簽名複製並放入代碼中,它一定可行。