在销毁所有对象后调用PHP函数

时间:2017-01-18 21:15:34

标签: php php-internals apcu bitweaver

我见过几个answers on object destruction order,并且都指出订单无法保证。由于我无法控制顺序,我想在所有对象被销毁后调用一个函数。

在对象销毁之前调用register_shutdown_function,因此不是一个选项。我使用该对象查看了set_error_handler这样的技巧,因此它被“迟到”调用,但这还不够。

问题的一些背景知识,这是一个complex CMS,有几十个单独的文件用于路由(视图)层。有一个常见的启动包括,但不是在关机时运行的常见启动。我通过公共继承的基类使用APCu对象缓存,并且需要确保清除对象。对于在页面加载期间创建的同一对象的任何两个实例,可能希望清除自身,而另一个可能想要自我缓存。显然purge胜过其他所有,所以我需要在一组全局缓存键上调用apc_delete来清除一个__destruct()'离子完成。

2 个答案:

答案 0 :(得分:4)

正如我在上面的评论中所说,多个对象实例的混合状态听起来像是一个设计缺陷。我认为你总是希望对象的所有实例都是最新的,或者至少不要触摸缓存,如果它们不是。我认为你的缓存和/或对象加载层可以处理这个问题。

为了回答你的基本问题,我写了a script to test PHP's shutdown sequence

<?php  /* Adapted from https://evertpot.com/160/ */

    ob_start(
        function($buffer) {
            return $buffer . "output buffer flushed\n";
        }
    );

    $empty = function() {
        return true;
    };

    $close = function() {
        echo "session close\n";
        return true;
    };

    $write = function() {
        echo "session write\n";
        return true;
    };

    session_set_save_handler($empty, $close, $empty, $write, $empty, $empty);
    session_start();

    register_shutdown_function(
        function() {
            echo "register_shutdown_function\n";
        }
    );

    class MyClass {
        function __destruct() {
           echo "object destructor\n";
        }
    }
    $myObject = new MyClass;

输出:

register_shutdown_function
object destructor
output buffer flushed
session write
session close

输出缓冲和会话写入/关闭的刷新似乎是你知道所有对象都被销毁的2个地方。 (这也假设您没有使用较新形式的session_set_save_handler,它可以将自己注册为关闭函数。)

答案 1 :(得分:0)

您是否尝试在__destruct()功能中调用此功能? PHP在销毁所有对象后调用此函数,因此它可能有所帮助。