2013-02-08 68 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'库类。将原始库函数签名复制并放入代码中,它一定可行。