Ich habe diese andere Frage angeschaut. Ich suche nach einer Möglichkeit zu tun, was das OP dieser Frage auch will, und das ist zu Verarbeitung von PHP nach dem Senden der HTTP-Antwort fortsetzen , aber in Symfony2.
Ich habe ein Ereignis implementiert, das nach jedem Kernel-Abbruch ausgelöst wird. So weit so gut, aber was ich will ist, dass es nach bestimmten Beendigungen, in bestimmten Controller-Aktionen, zum Beispiel nach dem Senden eines Formulars, nicht jedes Mal bei jeder Anfrage ausgelöst wird. Das liegt daran, dass ich zu bestimmten Zeiten einige schwere Aufgaben ausführen möchte und nicht möchte, dass der Endbenutzer auf das Laden der Seite wartet.
Irgendeine Idee, wie kann ich das tun?
%Vor%Bisher habe ich das Event beim kernel.terminate abonniert, aber offensichtlich wird es bei jeder Anfrage ausgelöst. Ich habe es Swiftmailers EmailSenderListener
ähnlich gemachtEs fühlt sich merkwürdig an, dass der Kernel jedes Mal auf dieses Ereignis hören muss, auch wenn es nicht ausgelöst wird. Ich hätte es lieber nur bei Bedarf abgefeuert, aber nicht sicher, wie das geht.
Im OnTerminate-Callback erhalten Sie eine Instanz von PostResponseEvent als ersten Parameter . Sie können sowohl die Anfrage als auch die Antwort von diesem Objekt erhalten. Dann sollten Sie in der Lage sein zu entscheiden, ob Sie den eigentlichen Beendigungscode ausführen möchten.
Sie können auch benutzerdefinierte Daten im Attribute-Feld der Anfrage speichern. Siehe diesen Link: Symfony und HTTP Fundamentals
Die Klasse Request besitzt auch eine Eigenschaft public attributes, die spezielle Daten enthält, die sich auf die interne Funktionsweise der Anwendung beziehen. Beim Symfony-Framework enthält das Attribut die Werte, die von der übereinstimmenden Route zurückgegeben werden, z. B. "_controller", "id" (wenn Sie ein id-Jokerzeichen haben) und sogar den Namen der übereinstimmenden Route (_route). Die Eigenschaft "attributes" existiert vollständig als ein Ort, an dem kontextspezifische Informationen über die Anfrage erstellt und gespeichert werden können.
Ihr Code könnte etwa so aussehen:
%Vor%Bearbeiten:
Das Ereignis kernel.terminate wird ausgeführt, nachdem die Antwort gesendet wurde. Aber die Symfony-Dokumentation sagt Folgendes (aus hier ) ):
Intern verwendet der HttpKernel die fastcgi_finish_request PHP-Funktion. Dies bedeutet, dass zur Zeit nur die PHP FPM Server API eine Antwort an den Client senden kann, während der PHP Prozess des Servers noch einige Aufgaben ausführt. Bei allen anderen Server-APIs werden Listener für kernel.terminate weiterhin ausgeführt, aber die Antwort wird erst an den Client gesendet, wenn sie alle abgeschlossen sind.
Bearbeiten 2:
Um die Lösung von hier zu verwenden, Sie könnten entweder direkt die Datei web / app.php bearbeiten, um sie dort hinzuzufügen (aber das ist eine Art "Hacking Core" imo, obwohl es einfacher zu verwenden wäre als das Folgende). Oder du könntest es so machen:
Ich habe es nicht versucht, aber es sollte tatsächlich funktionieren.
Ich habe diese Antworten verwendet, um eine Antwortklasse mit dieser Funktionalität zu schreiben: Ссылка
Diese Implementierung funktioniert mit Apache und nicht nur mit PHP FPM. Um dies zu ermöglichen, müssen wir Apache daran hindern, gzip zu verwenden (indem wir ein ungültiges Content-Encoding verwenden). Daher ist es sinnvoll, eine benutzerdefinierte Response-Klasse anzugeben, wenn eine frühe Antwort wichtiger ist als eine Komprimierung.
%Vor%Sie müssen auch eine Methode zu Ihrer AppKernel.php hinzufügen, damit dies funktioniert (vergessen Sie nicht, eine Use-Anweisung für Ihre EarlyResponse-Klasse hinzuzufügen)
%Vor%Tags und Links php symfony httpresponse