【发布时间】:2012-01-21 14:37:47
【问题描述】:
我有一个简单的自定义错误处理程序,它在错误日志文件中写入一些有用的调试信息。
它适用于一切,但不会因 FATAL 错误而触发。
有什么办法解决吗?
目前为了绕过这种情况,我也注册了一个关闭功能来检查error_get_last()
【问题讨论】:
标签: php error-handling fatal-error
我有一个简单的自定义错误处理程序,它在错误日志文件中写入一些有用的调试信息。
它适用于一切,但不会因 FATAL 错误而触发。
有什么办法解决吗?
目前为了绕过这种情况,我也注册了一个关闭功能来检查error_get_last()
【问题讨论】:
标签: php error-handling fatal-error
不,这只是set_error_handler() 的限制;它不能处理所有错误。
以下错误类型无法使用用户定义的函数处理:
E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING以及文件中引发的大部分E_STRICT其中set_error_handler()被调用。
register_shutdown_function() 和 error_get_last() 是一个不错的解决方法。
【讨论】:
解决它的方法只有 hackish,例如通过使用register_shutdown_function(),然后检查该函数内部是否发生错误。
PHP 有 log_errors 是有原因的,您可以在没有一行自定义代码的情况下将 PHP 记录 any 错误到 syslog 或日志文件中。因此,根本不需要为此目的使用set_error_handler(),除非您需要,否则应避免使用。堆栈跟踪。
【讨论】:
正如其他人指出的那样,我们可以按照以下方式使用 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
【讨论】: