是否可以捕获文件中发生的所有PHP错误

时间:2012-07-09 13:52:06

标签: php error-handling

我想在页面中捕获所有PHP错误(E_ERROR,E_WARNING,E_NOTICE,..)并将其记录到MongoDB,以便更好地阅读和评论。

我找到了一种方法,可以通过'error_get_last'捕捉上次发生的错误,并使用'register_shutdown_function'Handle fatal errors in PHP using register_shutdown_function()

将其发送到我想要的任何地方

但是,如果我的文件有多个错误,如警告和通知,我怎样才能获得文件中的所有错误?这可能吗?我需要的是'error_get_all'。

在这里你可以找到我的代码,这段代码有一个致命错误,两个警告和一个通知:

function shutdown() {
  $error = error_get_last();
  if ($error['type'] === E_ERROR || $error['type'] === E_WARNING || $error['type'] === E_NOTICE) {
    var_dump($error);
  }
}

register_shutdown_function('shutdown');

spl_autoload_register('foo');

$x = 5;
$y = 0;

echo 'x/y: ' . $x / $y . '<br/>';

foreach ($noarray as $noelement) {
  echo 'no element: ' . $noelement . '<br/>';
}

5 个答案:

答案 0 :(得分:4)

答案是结合解决方案:

使用'set_error_handler'捕获所有可能的错误(参见http://php.net/manual/en/function.set-error-handler.php),并使用描述的register_shutdown_function记录错过的错误。

通过执行此操作,运行时期间的非致命错误将被自定义处理程序捕获,一直持续到脚本结束或发生致命错误,该错误将由自定义或关闭函数捕获,具体取决于类型。

答案 1 :(得分:3)

使用set_error_handler

  

使用用户定义无法处理以下错误类型   功能:E_ERROR,E_PARSE,E_CORE_ERROR,E_CORE_WARNING,   E_COMPILE_ERROR,E_COMPILE_WARNING和大多数E_STRICT在   调用set_error_handler()的文件。

答案 2 :(得分:1)

要捕获致命错误并解析错误,请使用正确的功能

register_shutdown_function

但是当应用程序达到致命错误,或解析或任何错误E_ERROR执行过程结束于脚本的那一点时,所以在这种情况下你只能在脚本中捕获一个这样的错误。

我建议您使用register_shutdown_function以防万一,以便捕获致命错误,其他错误会捕获函数set_error_handler以捕获其他错误作为警告等,对于例外set_exception_handler您可以轻松跟踪系统中的所有错误并验证它们。

如果您要编写用于错误处理的对象,那么您的逻辑可以是:

$handler = new Handler();
$handler->handleExceptions(); //using set_exception_handler exceptions
$handler->handleError(E_ALL); //using set_error_handler all other errors
$handler->handleShutdown(); //using register_shutdown_function fatals, parsing

通过这种方式,您可以选择关闭/打开错误并将错误存储在您需要的位置或通过电子邮件从一个地方发送,这也是获得完全错误进行调试的简单方法。

答案 3 :(得分:0)

可能你想使用这样的框架: http://code.google.com/p/lagger/

答案 4 :(得分:-1)

遇到第一个遇到的致命错误是不可能捕获的,因为PHP解释器永远不会到达它们(脚本在执行关闭处理程序后终止)。可以捕获非致命错误(除了关闭处理程序之外,还需要为它们安装单独的error_handler),PHP不会终止脚本,所以如果你不在错误处理程序中终止它,在每次非致命错误之后执行将继续执行,您将全部捕获它们。如果你想在之后终止整个文件的执行,你可能想在某处保留一个标志,在包含文件之前将其清除,并在出现错误时将其抬起;在包含文件之后,您可以测试此标志并查看是否已捕获任何错误。请记住,包含的文件将在该点完全执行(如果它没有任何致命错误),或者您可能永远不会达到该点(如果它有致命错误)。

如果您运行的是不受信任的用户代码,则可能会对Runkit Sandboxes感兴趣。您还可以查看runkit_lint_file()进行一些预包含验证。