2017-01-18 71 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在銷燬所有對象後調用該函數,因此可能會有所幫助。

相關問題