4

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

我找到了一种使用“error_get_last”捕获最后发生的错误并使用“register_shutdown_function”将其发送到我想要的任何地方的方法使用 register_shutdown_function() 处理 PHP 中的致命错误

但是如果我的文件有多个错误,比如警告和通知,我怎样才能得到一个文件中的所有错误?这可能吗?我需要的是'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/>';
}
4

5 回答 5

4

答案是结合解决方案:

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

通过这样做,自定义处理程序将捕获运行时期间的非致命错误,一直持续到脚本结束或发生致命错误,该错误将由自定义或关闭函数根据类型捕获。

于 2012-07-09T14:00:13.900 回答
3

使用set_error_handler

用户定义的函数无法处理以下错误类型:E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING,以及在调用 set_error_handler() 的文件中引发的大部分 E_STRICT。

于 2012-07-09T13:53:55.963 回答
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

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

于 2016-07-15T12:53:02.717 回答
0

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

于 2012-07-09T13:56:14.430 回答
-1

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

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

于 2012-07-09T14:02:28.800 回答