2017-01-18 4 views
1

Ich habe mehrere answers on object destruction order gesehen, und alle weisen darauf hin, dass die Reihenfolge nicht garantiert ist. Da ich die Reihenfolge nicht kontrollieren kann, möchte ich eine Funktion aufrufen, nachdem alle Objekte zerstört wurden.Aufrufen einer PHP-Funktion, nachdem alle Objekte zerstört wurden

register_shutdown_function wird vor der Objektzerstörung aufgerufen, daher keine Option. Ich habe Tricks wie set_error_handler mit dem Objekt angeschaut, so dass es "spät" aufgerufen wird, aber das ist nicht ausreichend.

Einige Hintergrundinformationen zum Problem, das ist ein complex CMS mit Dutzenden von separaten Dateien für Routen (Ansicht) Ebene. Es gibt ein gemeinsames Boot-Include, aber kein allgemeines, das beim Herunterfahren ausgeführt wird. Ich verwende APCu-Objekt-Caching über eine gemeinsame geerbte Basisklasse und muss sicherstellen, dass ein Objekt gelöscht wird. Es ist möglich, dass für zwei Instanzen des gleichen Objekts, das während des Ladens einer Seite erstellt wurde, einer davon gelöscht werden soll und der andere sich selbst cachen möchte. Offensichtlich übertrumpft clean alles andere, also muss ich apc_delete auf einem globalen Satz von Cache-Schlüsseln aufrufen, um alle __destruct() 'Ionen zu löschen.

+1

Interessantes Problem. "Es ist möglich, dass für zwei Instanzen desselben Objekts, das während des Ladens einer Seite erstellt wurde, einer sich selbst löschen möchte und der andere sich selbst cachen möchte" klingt wie ein Konstruktionsfehler. Wollen Sie nicht immer, dass alle Instanzen eines Objekts die neuesten sind? Ich würde denken, dass Ihre Caching/Lade-Schicht damit umgehen würde. (Ich weiß nichts speziell über Bitweaver.) –

+1

Hallo Matt, der Designfehler Kommentar hat mich zum Nachdenken gebracht. Sie haben Recht, und jetzt werde ich einfach die bereinigte Liste überprüfen, bevor ich versuche, ein Objekt im Cache zu speichern. Es ist eine angemessenere Lösung, aber ich würde immer noch gerne wissen, wie man eine letzte "last call" -Funktion in PHP ausführt, wenn möglich. – Stickley

Antwort

3

Wie ich in meinem Kommentar oben gesagt habe, klingt der gemischte Zustand mehrerer Objektinstanzen wie ein Designfehler. Ich denke, dass Sie immer alle Instanzen eines Objekts als die neuesten haben möchten, oder zumindest den Cache nicht berühren, wenn sie nicht sind. Ich denke, dass Ihre Cache- und/oder Objektlade-Ebene damit umgehen könnte.


die zugrunde liegende Frage zu beantworten, habe ich 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; 

Der Ausgang:

register_shutdown_function 
object destructor 
output buffer flushed 
session write 
session close 

Es scheint, die bündig von Ausgabepufferung und Sitzungs Schreib-/schließen sind zwei Orte, an denen Sie wissen, dass alle Ihre Objekte zerstört wurden. (Dies setzt auch voraus, dass Sie nicht die neuere Form von session_set_save_handler verwenden, die sich selbst als Shutdown-Funktion registrieren kann.)

+0

Das ist großartig. Der session_close-Handler ist perfekt. – Stickley

0

Haben Sie versucht, die Funktion in der __destruct() Funktion aufzurufen? PHP ruft diese Funktion auf, nachdem alle Objekte zerstört wurden.

Verwandte Themen