PHP exec() Programm aufrufen & bei Bedarf killen

dr.White

Ensign
Registriert
Juli 2004
Beiträge
211
Ich starte ein Programm mit exec dessen Ausgabe dann im Browser dargestellt wird. Je nach Datenmenge kann das aber eine ganze Zeit dauern.

Wenn der Benutzer in dieser Zeit, während das Programm noch rechnet im Browser den "abbrechen" Button drückt dann wird die Ausgabe nicht mehr benötigt aber mein Programm auf dem Server rechnet immer noch weiter bis es fertig ist...

Wie kann ich das Programm beenden sobald im Browser abgebrochen wird, bzw der Browser geschlossen wird

thx4hlp
doc
 
Du kannst mittels register_shutdown_function() eine Funktion festlegen, die aufgerufen werden soll, sobald das Skript beendet wird, also sowohl wenn das Skript normal durchgelaufen ist, als auch wenn der Benutzer die Ausführung abgebrochen hat. Um innerhalb der Funktion dann die beiden Fälle zu unterscheiden, kannst du die Funktion connection_aborted() verwenden. Diese liefert true, wenn die Verbindung abgebrochen wurde.

Um das Programm zu beenden, hast du dann verschiedene Möglichkeiten. Wenn du das Programm selbst geschrieben hast, könntest du beispielsweise bei jedem Schritt der Berechnung abfragen, ob eine bestimmte Datei vorhanden ist, und wenn ja die Ausführung beenden. Dein PHP-Skript bräuchte dann nur diese Datei zu erzeugen, um das Programm "ordentlich" zu beenden. Auf einem Unix-System könntest du alternativ auch den Befehl "kill" verwenden, um den Prozess zu beenden.


Der einzige Nachteil an dieser Lösung ist, dass PHP üblicherweise erst bei der nächsten Ausgabe merkt, dass die Verbindung abgebrochen wurde. Du müsstest also für eine kontinuierliche Ausgabe sorgen, evtl. könnte das Programm ja den aktuellen Fortschritt bei der Berechnung ausgeben und du leitest die Ausgabe mittels passthru() weiter?
 
Hi!
vielen Dank erstmal für deine Hilfe. Deine Vorgehensweise hat mir sehr geholfen.
Da ich das Programm welches ich mit exec aufrufe nicht selbst geschrieben habe kann ich da nicht eingreifen. Es läuft unter Linux, also gibt es die Möglichkeit das Programm mit kill zu beenden... aber wie bekomme ich seine PID ? Es kann sein dass mehrere Instanzen des Programmes laufen, somit kann ich nicht anhand des Namens an die PID kommen... gibt es keine php Funktion die einen Prozess startet und die PID zurück liefert ?

Eine Alternative wäre ein shell script welches von php aufgerufen wird und dann das eigentliche Programm startet... aber wie bekomme ich da die PID ?

edit:
die PID bekomme ich inzwischen über pgrep bzw ps -aux | grep "xy"...

ein weiteres Problem ist, dass ich ja in meinem php script mit exec() das Programm starte und exec wartet so lange bis eine Antwort kommt... also kommt mein php script erst gar nicht dazu vorher register_shutdown_function aufzurufen um auf ein eventuelles abbrechen im browser mit connection_aborted reagieren zu können.

Ich dreh mich im Kreis...

mfg doc
 
Zuletzt bearbeitet:
vielleicht interessierts ja jemand,
mein shell script schreibt die PID in ein file welches mein php script vorher erzeugt hat und an die shell übergeben hat. ebenso schreibt mein shell script "finished" rein wenn es fertig ist. dann weiss php dass die ausgabe in einer anderen datei bereit liegt.
während der wartezeit gebe ich mit flush() immer "\r\n" zum browser aus und merke somit wenn der benutzer auf abbrechen gedrückt hat...

dann brauch ich nur noch die pid auslesen und in der der mit "register_shutdown_function(xy)" bestimmte Funktion mit connection_status() abfragen ob die Datei normal zu Ende glaufen ist oder ob ein Abbruch durch den Benutzer vorlag.
Dann ein kill auf meine pid und gut is...

Hat mich echt Nerven gekostet...
 
Zurück
Oben