使用register\u shutdown\u function()处理PHP中的致命错误

使用register\u shutdown\u function()处理PHP中的致命错误,php,error-handling,fatal-error,Php,Error Handling,Fatal Error,根据,可以通过无法使用set\u error\u handler()捕获的捕获致命错误 但是,我无法确定是由于致命错误还是由于脚本即将结束而导致关机 此外,在shutdown函数中,debug backtrace函数似乎已失效,这使得记录发生致命错误的堆栈跟踪变得毫无价值 所以我的问题是:在保持创建正确回溯的能力的同时,对致命错误(尤其是未定义的函数调用)做出反应的最佳方式是什么 function shutdown() { $error = error_get_last(); i

根据,可以通过无法使用
set\u error\u handler()
捕获的捕获致命错误

但是,我无法确定是由于致命错误还是由于脚本即将结束而导致关机

此外,在shutdown函数中,debug backtrace函数似乎已失效,这使得记录发生致命错误的堆栈跟踪变得毫无价值

所以我的问题是:在保持创建正确回溯的能力的同时,对致命错误(尤其是未定义的函数调用)做出反应的最佳方式是什么

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_错误中恢复


至于回溯,你不能(在大多数致命错误的情况下,尤其是未定义的函数错误,您并不真正需要它。精确定位发生错误的文件/行就足够了。在这种情况下,回溯是不相关的。

区分致命错误和使用register\u shutdown\u函数正确关闭应用程序的一种方法是定义一个常量作为最后一个li检查是否定义了常数:

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\u shutdown\u函数对于需要关闭错误报告的生产环境非常有用,但需要某种方式在后台记录错误,以便您可以响应。您还可以使用该函数在eve中将用户引导到友好的html页面这是一个很好的技巧,可以获得当前的错误处理程序方法=)


我也不想说如果你打电话

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

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

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