set_error_handler() 不适用于致命错误

问题描述 投票:0回答:4

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

它适用于所有事情,但不会因致命错误而触发。

有什么办法可以解决这个问题吗?

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

error_get_last()

php error-handling fatal-error
4个回答
26
投票

不,这只是

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()
是一个不错的解决方法。


5
投票

只有一些黑客的方法可以解决这个问题,例如使用

register_shutdown_function()
然后检查该函数内部是否发生错误。

PHP 具有

log_errors
的原因,您可以让 PHP 将 any 错误记录到系统日志或日志文件中,而无需一行自定义代码。因此,根本不需要为此目的使用
set_error_handler()
,并且应该避免,除非您需要例如堆栈跟踪。


4
投票

正如其他人指出的那样,我们可以按以下方式使用 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

0
投票

参见 https://www.php.net/manual/en/language.errors.php7.php

大多数错误可以使用

try catch finally
或 ser_exception_handler

进行处理

示例:

<?php

class A{
    public static $a=1;
}
try {
    unset(A::$a);
    
} catch(\Error $e){
    echo 'hello';
}
© www.soinside.com 2019 - 2024. All rights reserved.