【问题标题】:set_error_handler() doesn't work for FATAL errorset_error_handler() 不适用于致命错误
【发布时间】:2012-01-21 14:37:47
【问题描述】:

我有一个简单的自定义错误处理程序,它在错误日志文件中写入一些有用的调试信息。

它适用于一切,但不会因 FATAL 错误而触发。

有什么办法解决吗?

目前为了绕过这种情况,我也注册了一个关闭功能来检查error_get_last()

【问题讨论】:

标签: php error-handling fatal-error


【解决方案1】:

不,这只是set_error_handler() 的限制;它不能处理所有错误。

以下错误类型无法使用用户定义的函数处理:E_ERRORE_PARSEE_CORE_ERRORE_CORE_WARNINGE_COMPILE_ERRORE_COMPILE_WARNING 以及文件中引发的大部分 E_STRICT其中set_error_handler() 被调用。

register_shutdown_function()error_get_last() 是一个不错的解决方法。

【讨论】:

  • 你能举个例子说明使用 register_shutdown_function() 和 error_get_last() 作为我想不出的解决方法。
【解决方案2】:

解决它的方法只有 hackish,例如通过使用register_shutdown_function(),然后检查该函数内部是否发生错误。

PHP 有 log_errors 是有原因的,您可以在没有一行自定义代码的情况下将 PHP 记录 any 错误到 syslog 或日志文件中。因此,根本不需要为此目的使用set_error_handler(),除非您需要,否则应避免使用。堆栈跟踪。

【讨论】:

  • 当然,我需要我的第一篇文章中描述的堆栈跟踪和/或其他调试信息
【解决方案3】:

正如其他人指出的那样,我们可以按照以下方式使用 register_shutdown_function() 和 error_get_last()。

下面的实现将捕获在 php 7.1 中测试的 \Throwable 甚至没有捕获的错误。它也应该适用于以前的 PHP 版本。它只能在您的开发环境中实现(只需将其添加到您的开发配置文件中),不应在生产环境中完成。

实施

register_shutdown_function(function () {
    $err = error_get_last();
    if (! is_null($err)) {
        print 'Error#'.$err['message'].'<br>';
        print 'Line#'.$err['line'].'<br>';
        print 'File#'.$err['file'].'<br>';
    }
});

示例错误

Error# Class Path/To/MyService contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Path/To/MyServiceInterface::add)
Line# 12
File# Path/To/MyService.php

【讨论】:

  • 有没有办法恢复发生致命错误的代码?错误表示某些功能未定义。我想使用 eval() 定义该函数并将我的代码恢复到下一个错误。这可能吗?
  • @AhmadAmeri 不幸的是,在 PHP 发生致命错误后无法继续。您只能通过此 hack 捕获它们,并在它们发生时系统地删除它们。
猜你喜欢
  • 2014-10-24
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 2013-04-28
  • 2014-03-14
  • 2011-11-14
  • 2015-03-14
  • 2016-03-01
相关资源
最近更新 更多