【问题标题】:Invoking a PHP function after all objects have been destroyed销毁所有对象后调用 PHP 函数
【发布时间】:2017-06-03 10:19:19
【问题描述】:

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

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

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

【问题讨论】:

  • 有趣的问题。 “对于在页面加载期间创建的同一对象的任何两个实例,一个可能想要清除自己,而另一个可能想要缓存自己”听起来像是一个设计缺陷。你不总是希望一个对象的所有实例都是最新的吗?我认为您的缓存/加载层会处理这个问题。 (我对bitweaver一无所知。)
  • 嗨,马特,设计缺陷评论让我思考。您是对的,现在我将在尝试将对象存储在缓存中之前检查已清除列表。这是一个更合适的解决方案,但是如果可能的话,我仍然很想知道如何在 PHP 中执行最终的“最后调用”函数。

标签: php php-internals apcu bitweaver


【解决方案1】:

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


为了回答你的基本问题,我写了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

输出缓冲和会话写入/关闭的刷新似乎是您知道所有对象已被破坏的两个地方。 (这也假设您没有使用可以将自身注册为关闭函数的新形式的 session_set_save_handler。)

【讨论】:

  • 这很棒。 session_close 处理程序非常完美。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-28
    • 2011-05-24
    • 1970-01-01
    • 2012-06-25
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多