根据 关于这个答案的评论 可以通过 关闭功能 不能使用 set_error_handler().

但是,我找不到如何确定由于致命错误还是由于脚本达到其末尾而发生的关闭。

此外,在关闭功能中,调试回溯函数似乎已停用,这对于记录发生致命错误的堆栈跟踪非常有价值。

因此,我的问题是:在致命错误(尤其是未定义的功能调用)中,在保持适当的回溯能力的同时,最佳反应方式是什么?

有帮助吗?

解决方案

这对我有用:

function shutdown() {
    $error = error_get_last();
    if ($error['type'] === E_ERROR) {
        // fatal error has occured
    }
}

register_shutdown_function('shutdown');

spl_autoload_register('foo'); 
// throws a LogicException which is not caught, so triggers a E_ERROR

但是,您可能已经知道了,但是只是为了确保:您无法以任何方式从e_error恢复。

至于回溯,你不能... :(在大多数情况下,尤其是 未定义的功能 错误,您真的不需要它。精确指出发生的文件/线就足够了。在这种情况下,回溯无关紧要。

其他提示

通过register_shutdown_function区分致命错误和正确关闭应用程序的一种方法是将常数定义为程序的最后一行,然后检查是否定义了常数:

function fatal_error() {
if ( ! defined(PROGRAM_EXECUTION_SUCCESSFUL)) {
        // fatal error has occurred
    }
}

register_shutdown_function('fatal_error');

define('PROGRAM_EXECUTION_SUCCESSFUL', true);

如果程序达到末尾,则不可能遇到致命错误,因此,如果定义常数,我们知道不运行该功能。

error_get_last()是一个数组,其中包含有关您需要调试的致命错误的所有信息,尽管它不会像提到的那样具有返回。

通常,如果您的PHP程序遇到了致命错误(与例外相反),则希望该程序爆炸,以便您可以找到并解决该问题。我发现register_shutdown_function对您要关闭错误报告的生产环境有用,但需要某种方法来记录后台错误,以便您可以响应它。您也可以使用该函数将用户引导到友好的HTML页面,但如果您出现了这样的错误,则不仅仅是为空白页提供。

只是获取当前error_handler方法=)的一个不错的技巧=)

<?php
register_shutdown_function('__fatalHandler');
function __fatalHandler()
{
    $error      = error_get_last();

    //check if it's a core/fatal error, otherwise it's a normal shutdown
    if($error !== NULL && $error['type'] === E_ERROR) {
        //Bit hackish, but the set_exception_handler will return the old handler
        function fakeHandler() { }
        $handler = set_exception_handler('fakeHandler');
        restore_exception_handler();
        if($handler !== null) { 
            call_user_func($handler, new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']));
        }
        exit;
    }
}
?>

我也不要注意,如果你打电话

<?php
ini_set('display_errors', false);
?>

PHP停止显示错误,否则错误文本将在您的错误处理程序之前发送到客户端

我为此使用“ ob_start”。

function fatal_error_handler($buffer) {
    if (preg_match("|(Fatal error:)(.+)|", $buffer, $regs) ) {
        //Your code
    }
    return $buffer;
}
ob_start("fatal_error_handler");
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top