2010-09-25 50 views
3

我即將開始在我的框架中實現錯誤處理並尋找關於如何構建它的一些建議。對我的框架實現錯誤處理

首先讓我解釋一下我的框架,目前是如何建立起來的:

林分離應用程序啓動框架的啓動,所以導致應用程序啓動中的任何錯誤都應該由專門的那類專門處理。

我的想法是有一個叫Core_Error_exception女巫類將設置錯誤E_ALL報告作爲我的框架將是嚴格的誤差爲PHP 5.3,然後根據我的我的應用程序負載我將運行中的關機功能功能該類恢復所有默認值已更改。

什麼即時希望做的是捕捉那些E_*_NOTICE而不是E_*_ERROR,然後應用程序啓動時我告訴類停止捕獲錯誤爲Application_Error_Exception前會看出來的錯誤的所有錯誤。

所以我需要一種方法來跟蹤包括異常和觸發器在內的所有錯誤,然後在應用程序初始化之前顯示一個框架調試頁面。

那種類我一直在尋找的是,像這樣:

class Core_Error_Exception 
{ 
    var $previus_error_level,$captured_contents; 

    private $stack_trace = array(); 

    public function Core_Error_Exception() 
    { 
     $this->previus_error_level = error_reporting(-1); 
     set_error_handler(array($this,'_collect_error')); 
     set_exception_handler(array($this,'_collect_error')); 
     ob_start(array($this,'_capture')); 
    } 

    public function _collect_error($errno, $errstr, $errfile, $errline, $context) 
    { 
     $this->stack_trace[] = array(
      array('name' => 'Error ID:', 'value' => $errno), 
      array('name' => 'Error String:','value' => $errstr), 
      array('name' => 'Error File:', 'value' => $errfile), 
      array('name' => 'Error Line:', 'value' => $errline), 
      array('name' => 'Context PRE:', 'value' => $context) 
     ); 
     var_dump($this->stack_trace); 
    } 

    /* 
    * _capture is used to capture pre_bufferd content. 
    */ 
    public function _capture($content,$bitfeild) 
    { 
     if($bitfeild & PHP_OUTPUT_HANDLER_START) 
     { 
      $this->captured_contents = $content; 
     } 

     if($bitfeild & PHP_OUTPUT_HANDLER_CONT) 
     { 
      $this->captured_contents .= $content; 
     } 

     if($bitfeild & PHP_OUTPUT_HANDLER_END) 
     { 
      $this->captured_contents .= $content; 
     } 
     return false; 
    } 
} 

那麼什麼即時希望做的是要能夠構建一個秋天,防爆方式這一類,以便任何通知的錯誤可能已被觸發的數據將被放入數組中,如果調用了E_ERROR通知,則會自動在該點執行關閉操作,以防止導致更多錯誤。

我將使用一個小的html模板處理程序,我可以將這些錯誤傳遞到上下文中,因此注意錯誤和單個E_*_ERROR(如果適用)。

什麼是過去構建這個類的最好方法我在做錯誤跟蹤/報告時遇到了一些困難。

更新:與當前類

如果錯誤觸發的諸如trigger_error( '測試',XXX);我希望能夠跟蹤所有錯誤,直到應用程序啓動或E_USER_ERROR被觸發。

有時候我很難完全掌握PHP的錯誤系統,等等,因爲有時候我會爲如何構建它而感到困惑,所以它的防摔能力。

回答

3

我不太清楚你在做什麼,但最簡單的方法是使用嵌套的try塊,沿

in Class Application: 

    function run() { 
     try { 
      --do stuff 
     } catch(AppException $e) { 
      -- handle application-level exception 
     } 
     -- all other exceptions fall through 


in Class Core: 

    try { 
     $core->init(); 
     $application->run(); <-- calls the above function 
     $core->done(); 
    } catch(Exception $e) { 
     --last chance exception handler 
     --process exceptions the Application was unable to handle on its own 
    } 

行爲了能夠捕獲php內置錯誤或trigger_error事件這種方式,你也應該總是安裝一個errors-to-exceptions handler

+0

豎起大拇指,這是最可靠的方式來做到這一點。 – 2010-09-25 10:11:44

+0

但這隻適用於瞭解異常的人,很多用戶不會這麼做,所以我也跟蹤可能未捕獲的錯誤,甚至觸發'trigger_error' – RobertPitt 2010-09-25 10:19:44

+0

@Robert,好點,請參閱更新。 – user187291 2010-09-25 10:36:24

0

你有什麼看起來很穩固。您將不得不添加一些邏輯,以便在拋出錯誤時關閉腳本以在ob緩衝區中刷新輸出,並將所有收集的數據發送到錯誤HTML文件以顯示跟蹤。喜歡的東西:

public function _collect_error($errno, $errstr, $errfile, $errline, $context) 
{ 
    $this->stack_trace[] = array(
     array('name' => 'Error ID:', 'value' => $errno), 
     array('name' => 'Error String:','value' => $errstr), 
     array('name' => 'Error File:', 'value' => $errfile), 
     array('name' => 'Error Line:', 'value' => $errline), 
     array('name' => 'Context PRE:', 'value' => $context) 
    ); 

    if($errno == E_USER_ERROR) { 
     ob_clean(); 
     // Pass collected data to HTML template 
     // Display HTML 
     exit(); 
    } 

    var_dump($this->stack_trace); 
} 

我不是100%肯定,你可以優雅地從致命的錯誤中恢復,但是從你說的話你只是在尋找特定的非致命錯誤關閉處理。

你還有什麼意圖捕獲緩衝內容?如果你正在尋找的錯誤沒有被擊中或者被拋出,並且顯示錯誤屏幕(爲什麼我在錯誤函數中添加了ob_clean),我會假設它顯示?

+0

ob_clean只是爲了保護錯誤,例如從庫的un起始空間和預先發送的文本,直到啓動應用程序。 – RobertPitt 2010-09-25 14:30:03

+1

正確。意思是ob_end_clean。 – methodin 2010-09-25 15:32:36

+0

只是一個小小的疏忽,認爲ove記錄它:http://pastebin.com/2kWyDcNJ,只是執行開始();在加載所有內核之前,adn stop();在應用程序啓動之前。迄今爲止效果很好:) – RobertPitt 2010-09-25 17:02:10