2014-09-02 28 views
0

所以在php.ini我設置:PHP error_get_last在收到警告,儘管error_handling = 1

error_reporting = E_ERROR 

,我已經寫了一個處理程序:

register_shutdown_function("fatal_handler"); 

function fatal_handler() { 

    $errfile = "unknown file"; 
    $errstr = "shutdown"; 
    $errno = E_CORE_ERROR; 
    $errline = 0; 

    $error = error_get_last(); 

    if($error !== NULL) { 
    $errno = $error["type"]; 
    $errfile = $error["file"]; 
    $errline = $error["line"]; 
    $errstr = $error["message"]; 

    if($errno == E_ERROR){ 
     $html = 'some html here'; 
     print($html); 
     die(); 
    } 
    } 
} 

我所做的測試它是在一個腳本中放置超過max_execution_time的睡眠時間。出於某種原因,如果我在加載故意破壞的標籤時在另一個標籤中打開新標籤,也會殺死其他頁面。沒關係,但是當第二頁崩潰時,它給了我一個error_get_last()的警告。但我把error_reporting設置爲1!爲什麼它顯示我一個警告?它不會記錄它,但它會導致我無法捕獲導致白屏的錯誤,這個代碼應該避免的確切事情!

回答

1

所以基本上我已經採取了埃文的回答,並與this question's answer結合起來,我有什麼似乎是一個可行的解決方案。如果error_reporting設置爲記錄它們,myHandler會捕獲錯誤/警告並記錄它們。然後它返回true,這將防止警告進入error_get_last()。所以現在error_get_last()調用應該只返回[繞過錯誤處理程序的東西],比如E_ERROR。

register_shutdown_function('fatal_handler'); 
set_error_handler('myHandler'); 

function myHandler($errno, $errstr, $errfile, $errline, $errctx){ 
    if((error_reporting() & $errno) && ini_get('log_errors') == 'On'){ 
     error_log(getFriendlyErrorType($errno) . ': ' . $errstr . ' in ' . $errfile . ' on line ' . $errline); 
    } 
    return true; 
} 

function fatal_handler() { 
    $error = error_get_last(); 

    if($error !== NULL) { 
     $errno = $error["type"]; 
     $errfile = $error["file"]; 
     $errline = $error["line"]; 
     $errstr = $error["message"]; 

     if($errno == E_ERROR){ 
      $html = '[some html]'; 
      print($html); 
      die(); 
     } 
    } 
} 

function getFriendlyErrorType($type) 
{ 
    switch($type) 
    { 
     case E_ERROR: // 1 // 
      return 'PHP Error'; 
     case E_WARNING: // 2 // 
      return 'PHP Warning'; 
     case E_PARSE: // 4 // 
      return 'PHP Parse'; 
     case E_NOTICE: // 8 // 
      return 'PHP Notice'; 
     case E_CORE_ERROR: // 16 // 
      return 'PHP Core Error'; 
     case E_CORE_WARNING: // 32 // 
      return 'PHP Core Warning'; 
     case E_CORE_ERROR: // 64 // 
      return 'PHP Compile Error'; 
     case E_CORE_WARNING: // 128 // 
      return 'PHP Compile Warning'; 
     case E_USER_ERROR: // 256 // 
      return 'PHP User Error'; 
     case E_USER_WARNING: // 512 // 
      return 'PHP User Warning'; 
     case E_USER_NOTICE: // 1024 // 
      return 'PHP User Notice'; 
     case E_STRICT: // 2048 // 
      return 'PHP Strict Standards'; 
     case E_RECOVERABLE_ERROR: // 4096 // 
      return 'PHP Recoverable Error'; 
     case E_DEPRECATED: // 8192 // 
      return 'PHP Deprecated'; 
     case E_USER_DEPRECATED: // 16384 // 
      return 'PHP User Deprecated'; 
    } 
    return ''; 
} 
2

既不關閉處理程序也不error_get_last榮譽error_reporting。

關機處理程序將始終被調用,無論任何錯誤或它的級別(除非你拋出一個異常的自定義錯誤處理程序內)

error_get_last只是給你的最後一個錯誤,不管它的水平。

而不是使用關閉處理程序,爲什麼不使用錯誤處理程序?在這種情況下,如果您想忽略該級別的錯誤,您可以檢查錯誤級別並返回FALSE。 (返回FALSE告訴PHP將正常進行)

set_error_handler("fatal_handler"); 

function fatal_handler($errno, $errstr, $errfile, $errline, $errctx) 
{ 
    $reptLevel = error_reporting(); 

    if ($reptLevel > 0) //if $reptLevel = 0 then it means the code that caused the error was preceded by a supressor (example: $x = @someFunction()) 
    { 
     if ($errno == E_ERROR) 
     { 
      $html = 'some html here'; 
      print($html); 
      die(); 
     } else { 
      return false; 
     } 
    } 
} 
+0

看來E_ERROR從來沒有把它變成這個方法。我從[這個問題]得到了原始代碼(http://stackoverflow.com/questions/277224/how-do-i-catch-a-php-fatal-error)。嗯... – Andrew 2014-09-03 14:43:08

+0

啊哈!但是,如果我結合你的答案,我想我正在做一件事。 – Andrew 2014-09-03 14:58:47

+0

@andrew你是對的我忘記了。到達關機處理程序時,輸出的數據已經發送。所以,如果你是白人篩查,那麼或許警告或錯誤阻止了輸出的發送? – 2014-09-03 17:10:49