2009-09-17 3 views
6

ich konfigurieren mein Skript zunächst auch nach der HTTP-Anforderung ist überKann ein PHP-Skript den Browser dazu verleiten zu glauben, dass die HTTP-Anfrage vorbei ist?

ignore_user_abort(true); 

dann auszuspülen einen Text zu laufen.

echo "Thats all folks!"; 
flush(); 

Nun, wie kann ich den Browser glauben, dass die HTTP-Anfrage vorbei ist? damit ich meine eigene Arbeit fortsetzen kann, ohne dass der Browser "page loading" anzeigt.

header(??) // something like this? 

Antwort

10

Hier ist, wie es geht. Sie weisen den Browser an, die ersten N Zeichen der Ausgabe einzulesen und dann die Verbindung zu schließen, während Ihr Skript weiterläuft, bis es fertig ist.

<?php 
ob_end_clean(); 
header("Connection: close"); 
ignore_user_abort(true); // optional 
ob_start(); 
echo ('Text the user will see'); 
$size = ob_get_length(); 
header("Content-Length: $size"); 
ob_end_flush();  // Will not work 
flush();   // Unless both are called ! 

// At this point, the browser has closed connection to the web server 

// Do processing here 
echo('Text user will never see'); 
?> 
+0

+1 Brillante Lösung! Danke für die Weisheit, die alle Reiter des Königs nicht herausfinden konnten. –

+0

Wirklich netter Hack von Milan. Aber ich muss mich fragen, was Sie tun, das erfordert, einen Web-Server-Prozess zu kauen, nachdem die Web-Anfrage vorbei ist (aus der Sicht des Kunden). Ich hoffe natürlich, dass diese Abscheulichkeit wird nicht sehr stark skalieren! – timdev

+3

Identisch (zum Buchstaben) zu dem Code in der PHP-Handbuchseite, die mit in Lukmans Antwort verbunden ist, die zwei Tage zuvor gepostet wurde. – GZipp

4

Header wird nicht funktionieren (sie sind Header, so kommen sie erste)

Ich weiß nicht von irgendeiner Weise die HTTP-Verbindung zu schließen, ohne das Skript beendet wird, obwohl ich glaube, Es gibt einen obskuren Weg, es zu tun.

Wenn Sie uns mitteilen, was Sie nach der Anfrage tun möchten, helfen Sie uns, bessere Vorschläge zu machen.

Aber im Allgemeinen, würde ich das über eine der folgenden denken:

1) Führen Sie einige einfache Befehlszeilenskript (mit exec()), der wie folgt aussieht:

#!/bin/sh 
php myscript.php <arg1> <arg2> .. <argN> & 

Dann Kick dass von Ihrem http gebundenen Skript ab wie:

<?PHP 
exec('/path/to/my/script.sh'); 
?> 

Oder:

2) schreiben anothe r-Programm (möglicherweise ein kontinuierlich laufender Daemon oder einfach nur ein Skript, das so oft erstellt wird) und herausfinden, wie Ihr In-Anfrage-Code Anweisungen übergeben kann. Sie könnten eine Datenbanktabelle haben, die die Arbeit in die Warteschlange stellt, oder versuchen, sie mit einer flachen Datei von irgendeiner Art arbeiten zu lassen. Sie könnten auch Ihr webbasiertes Skript einen Befehlszeilenbefehl aufrufen lassen, der dazu führt, dass Ihr nicht angefordertes Skript einige Aufgaben in die Warteschlange stellt.

Am Ende des Tages, Sie nicht wollen Ihr Skript nach der http-Anfrage weiter ausführen. Angenommen, Sie verwenden mod_php, bedeutet das, dass Sie einen Apache-Prozess binden, bis das Skript beendet wird.

+1

+1 Einverstanden. Eine fortgesetzte Ausführung nach einer Webanforderung wäre eine schlechte Designauswahl und würde unnötigen Speicheraufwand auf dem Server verursachen. – Fragsworth

+0

Große Zeit stimmte mit Tim überein. Der springende Punkt der Frage ist, dass Sie einen Teil der Arbeit für später speichern und den Benutzer nicht warten lassen wollen. Nun, Sie binden nur httpd-Ressourcen, die andere Benutzer blockieren könnten. Lassen Sie httpd Web-Clients behandeln und übergeben Sie die andere Arbeit an eine andere Komponente - Daemon (+1 für Echtzeit), geplanten Job (+1 für Batch-und Warteschlange erata Verarbeitung, die wirklich warten kann), oder was auch immer. –

2

Wenn HTTP 1.1 keep-alive aktiviert ist und der Client die Anzahl der vom Server erwarteten Zeichen erhält, sollte er sie als Ende der Antwort behandeln und die Seite rendern (unter Beibehaltung der Verbindung) Versuchen Sie immer noch offen) diese Header zu senden (wenn Sie ihnen eine andere Art und Weise nicht aktivieren können.):

 
Connection: keep-alive 
Content-Length: n 

Wo n die Menge der Zeichen, die Sie im Antworttext gesendet haben (Ausgabepufferung helfen können Sie sich verlassen dass.) Es tut mir leid, dass ich nicht die Zeit habe, das selbst zu testen. Ich werfe nur den Vorschlag ein, falls es funktioniert.

+0

Noch eine schlechte Idee, als ob die Post-Anfrage-Verarbeitung dauert mehr als ein paar ms (in diesem Fall, warum die Eile, um die Verbindung zu beenden), Sie besser den Web-Server-Prozess freigeben, um neue Anfragen zu behandeln, und einige haben Back-End-Prozess (nicht an den httpd gebunden) übernehmen. – timdev

+0

Ich stimme zu, dass dies wahrscheinlich eine schlechte Idee ist. Es ist nur ein Versuch, die Anforderung des OP zu erfüllen. –

2

Der beste Weg, diese Ausgabe-Pufferung zu erreichen verwendet. PHP sendet die Header, wenn es gut und fertig ist, aber wenn Sie Ihre Ausgabe mit ob_ * in den Browser schreiben, können Sie die Header bei jedem Schritt des Weges steuern.

Sie können eine gerenderte Seite im Puffer halten, wenn Sie möchten, und senden Sie Header, bis die Sonne in China aufgeht. Aus diesem Grund können Sie viele öffnende Tags sehen, aber keine schließenden Tags. Es verhindert, dass das Skript Header vorzeitig sendet, da möglicherweise einige Includes berücksichtigt werden müssen.

Verwandte Themen