2017-01-18 44 views
1

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

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

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

+1

有趣的问题。 “对于页面加载过程中创建的同一对象的任何两个实例,有可能需要自行清除,而另一个可能需要自行缓存”听起来像是一个设计缺陷。你不是总希望一个对象的所有实例都是最新的吗?我认为你的缓存/加载层可以处理这个问题。 (我不知道什么关于bitweaver具体。) –

+1

嗨马特,设计缺陷评论让我思考。您是正确的,现在我只是在尝试将对象存储在缓存之前检查清除的列表。这是一个更合适的解决方案,但是如果可能的话,我仍然很想知道如何在PHP中执行最后的“最后一次调用”函数。 – Stickley

回答

3

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


要回答你的根本问题,我写了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的新形式,它可以将自己注册为关机功能。)

+0

这太好了。 session_close处理程序是完美的。 – Stickley

0

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