In PHP wird die Funktion ignore_user_abort () häufig verwendet, damit Skripte die Ausführung fortsetzen können, nachdem der Benutzer getrennt ist (z. B. das Schließen des Browsers oder das Trennen des Netzwerks). Viele Entwickler werden jedoch feststellen, dass es während der Verwendung nicht wirksam wird, und das Skript wird immer noch beendet, weil der Benutzer die Verbindung trennen. Dieser Artikel wird die Ursachen dieses Problems eingehend analysieren und einige gemeinsame Lösungen zusammenfassen.
Ignore_User_abort () ist eine integrierte Funktion von PHP, die einen booleschen Parameter akzeptiert. Nachdem PHP diese Funktion aufgerufen und true angerufen hat, ignoriert er das Disconnect -Ereignis des Benutzers und führt das aktuelle Skript weiter aus, bis es abgeschlossen ist oder aktiv beendet wird.
<?php
ignore_user_abort(true);
echo "Das Skript beginnt auszuführen\n";
// Angenommen, einige zeitaufwändige Aufgaben werden ausgeführt
sleep(30);
echo "Ende der Skriptausführung\n";
?>
Der obige Code muss theoretisch die Ausführung fortsetzen, auch wenn der Benutzer den Browser schließt.
Der Ausführungsmodus von PHP variiert:
CLI -Modus : Normalerweise endet er nicht, da der Benutzer getrennt ist, da es kein Konzept einer Browserverbindung gibt.
CGI/FASTCGI -Modus : Möglicherweise wird durch die Webserverkonfiguration eingeschränkt, und die Nutzerunterbrechung kann nicht vollständig ignoriert werden.
Apache mod_php : Im Allgemeinen wird Ignore_User_abort unterstützt, aber Sie sollten auch auf die Konfiguration achten.
Wenn das Skript einen Ausgabebuffer hat, erkennt der Server es nicht rechtzeitig, wenn der Browser getrennt wird, wodurch der PHP -Prozess das Trennereignis nicht genau kennt und so die Einstellungen ignoriert.
Lösung: Schalten Sie den Ausgangspuffer aus oder aktualisieren Sie sie.
<?php
ignore_user_abort(true);
ob_end_flush(); // Ausschalten der Ausgangspufferung ausschalten
flush(); // Senden Sie die Ausgabe an den Browser
sleep(30);
?>
max_execution_time in der PHP -Konfiguration begrenzt die maximale Ausführungszeit des Skripts, und das Skript wird gezwungen, nach der Ankunftszeit zu enden.
Lösung: MAX_EXECUTION_TIME oder Rufen Sie an
<?php
set_time_limit(0); // Skriptausführungszeitlimit abbrechen
ignore_user_abort(true);
?>
Einige Webserver oder Reverse -Proxy (z. B. Nginx) beenden die Trennanforderung proaktiv und bewirken, dass der PHP -Prozess ein Terminierungssignal empfängt.
Lösung:
Bestätigen Sie die Zeitüberschreitungseinstellungen für Server und Agent.
Verwenden Sie eine asynchrone Task-Warteschlange oder ein Hintergrund-Dämon, um langfristige PHP-Skripte zu ersetzen.
<?php
ignore_user_abort(true);
echo "Führen Sie Aufgaben aus\n";
sleep(30);
echo "Mission endet\n";
?>
Wenn der Browser getrennt ist, kann das Skript unterbrochen werden, da die Ausgabe nicht sofort gesendet wird, wodurch der Server nicht überwacht werden kann.
<?php
ignore_user_abort(true);
set_time_limit(0);
echo "Führen Sie Aufgaben aus\n";
ob_end_flush();
flush();
sleep(30);
echo "Mission endet\n";
?>
Frage | Lösung |
---|---|
Das Skript endet aufgrund der Nutzer -Trennung | Ignore_user_abort (true) |
Die Ausführungszeit der Skript ist begrenzt | set_time_limit (0) |
Der Ausgang wird nicht sofort gesendet, wodurch die Trennung erkannt wird | Schalten Sie die Ausgabe aus, die OB_END_FLUSH () ausgaberisieren und Flush () aufrufen |
Server -Timeout oder Proxy -Einschränkung | Passen Sie die Serverkonfiguration an und verwenden Sie Hintergrundaufgabenmethoden |
Ignore_User_abort () ist nicht allmächtig, insbesondere in komplexen Serverumgebungen, wenn das Aufrufen dieser Funktion das Skript nicht garantieren kann, dass das Skript kontinuierlich ausgeführt wird. Nur durch Kombination angemessener Ausgabesteuerung, Ausführungszeiteinstellungen und Serverkonfiguration können ideale Ergebnisse erzielt werden. Gleichzeitig wird für langfristige Aufgaben empfohlen, Nachrichtenwarteschlangen oder Hintergrund-Daemon-Design zu verwenden, um die Systemstabilität und Skalierbarkeit zu verbessern.
<?php
// Typische Nutzungsdemonstration
ignore_user_abort(true);
set_time_limit(0);
echo "Mission beginnt\n";
ob_end_flush();
flush();
for ($i = 0; $i < 10; $i++) {
// Simulieren Sie langlebige Aufgaben
sleep(3);
echo "Zeitplan:$i\n";
flush();
}
echo "Aufgabe Abschluss\n";
?>