调用undefined方法时不调用shutdown回调

时间:2012-07-13 20:56:38

标签: php

考虑以下两个PHP(5.4)脚本。为什么仅在执行脚本A时调用传递给register_shutdown_function的回调,而不是在执行脚本B时调用?

脚本A

set_error_handler(function() {
    throw new Exception();
});
register_shutdown_function(function() {
    echo "shutdown handler invoked\n";
});

undefined();
// "shutdown handler invoked" IS displayed

脚本B

set_error_handler(function() {
    throw new Exception();
});
register_shutdown_function(function() {
    echo "shutdown handler invoked\n";
});

$undefined->undefined();
// "shutdown handler invoked" IS NOT displayed

2 个答案:

答案 0 :(得分:1)

这是一个错误 - 如果在set_error_handler注册的可调用异常引发异常,则不会调用shutdown函数。

在这种特殊情况下,会发生以下事件链:

  1. 触发非致命错误(未定义变量:未定义)
  2. 调用用户错误处理程序
  3. 抛出异常
  4. 触发致命错误(在非对象上调用成员函数undefined())
  5. 由于现有异常
  6. ,未调用关机功能

    https://bugs.php.net/61767(带补丁!)和https://bugs.php.net/60909的现有错误报告包含其他详细信息。

答案 1 :(得分:0)

这是我发现的。

退出时调用register_shutdown_function。

$ undefined->未定义();触发E_NOTICE错误,因为$ undefined未定义为通过set_error_handler的变量。如果你调用throw new Exception,php出于某种原因在退出崩溃时不触发register_shutdown_function处理程序,如果你想抛出异常,也许你可以直接调用你的异常函数。

如果你创建一个虚拟类并定义$ undefined,但是没有创建一个名为undefined的成员函数,它的行为方式与调用undefined()的行为相同,如下所示

未定义();触发E_ERROR,它立即退出触发shutdown_function处理程序

您可以在关闭功能旁边使用错误处理程序来捕获不同类型的错误:

function shutdown_function_handler(){
    if ($error = error_get_last()){
        switch ($error['type']){
            case E_ERROR:
            case E_USER_ERROR:
            case E_CORE_ERROR:
            case E_COMPILE_ERROR:
                echo " ERRROR:".$error['message'];
        }
    }
}