Heim >Backend-Entwicklung >PHP-Tutorial >Codebeispiel für die Verwendung von fscok zur Implementierung eines asynchronen Aufrufs von PHP

Codebeispiel für die Verwendung von fscok zur Implementierung eines asynchronen Aufrufs von PHP

黄舟
黄舟Original
2017-03-30 10:03:321533Durchsuche

Der Webserver führt ein Skript aus, das möglicherweise in wenigen Millisekunden oder auch nicht in mehreren Minuten abgeschlossen ist. Wenn das Programm langsam ausgeführt wird, hat der Benutzer möglicherweise nicht die Geduld, länger zu warten und den Browser zu schließen.

Manchmal kümmern wir uns nicht einmal um die Ausführungsergebnisse dieser zeitaufwändigen Skripte, sondern wir müssen warten, bis die Ausführung abgeschlossen ist und sie zurückkehren, bevor wir mit dem nächsten Schritt fortfahren können.
Gibt es also eine Möglichkeit, einfach den Aufruf dieser zeitaufwändigen Skripte auszulösen und dann mit dem nächsten Schritt fortzufahren, sodass diese zeitaufwändigen Skripte serverseitig langsam ausgeführt werden können?

Als nächstes werde ich fscokopen verwenden, um diese Funktion zu implementieren.
                                                                        using  socket                     using   using   using  socket  
  mit fsockopen. fscokopen gibt ein Handle für die Remote-Host-Verbindung zurück. Sie können fwrite,
fgets, fread und andere Operationen an ihr ausführen, genau wie mit dem von fopen zurückgegebenen Handle.
Der wichtigste gewünschte Effekt unseres asynchronen PHP besteht darin, ein PHP-Skript auszulösen und dann sofort zurückzukehren, sodass es langsam auf der Serverseite ausgeführt werden kann. Ich habe vorhin auch einen Artikel geschrieben, um dieses Problem zu diskutieren.

Anschließend können wir mit fsockopen eine Verbindung zum lokalen Server herstellen, die Skriptausführung auslösen und dann sofort zurückkehren, ohne auf den Abschluss der Skriptausführung warten zu müssen.


function triggerRequest($url, $post_data = array(), $cookie = array())…{
        $method = "GET";  //可以通过POST或者GET传递一些参数给要触发的脚本
        $url_array = parse_url($url); //获取URL信息,以便平凑HTTP HEADER
        $port = isset($url_array['port'])? $url_array['port'] : 80; 
      
        $fp = fsockopen($url_array['host'], $port, $errno, $errstr, 30); 
        if (!$fp) …{
                return FALSE;
        }
        $getPath = $url_array['path'] ."?". $url_array['query'];
        if(!empty($post_data))…{
                $method = "POST";
        }
        $header = $method . " " . $getPath;
        $header .= " HTTP/1.1\r\n";
        $header .= "Host: ". $url_array['host'] . "\r\n "; //HTTP 1.1 Host域不能省略
        /**//*以下头信息域可以省略
        $header .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13 \r\n";
        $header .= "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,q=0.5 \r\n";
        $header .= "Accept-Language: en-us,en;q=0.5 ";
        $header .= "Accept-Encoding: gzip,deflate\r\n";
         */

        $header .= "Connection:Close\r\n";
        if(!empty($cookie))…{
                $_cookie = strval(NULL);
                foreach($cookie as $k => $v)…{
                        $_cookie .= $k."=".$v."; ";
                }
                $cookie_str =  "Cookie: " . base64_encode($_cookie) ." \r\n";//传递Cookie
                $header .= $cookie_str;
        }
        if(!empty($post_data))…{
                $_post = strval(NULL);
                foreach($post_data as $k => $v)…{
                        $_post .= $k."=".$v."&";
                }
                $post_str  = "Content-Type: application/x-www-form-urlencoded\r\n";//POST数据
                $post_str .= "Content-Length: ". strlen($_post) ." \r\n";//POST数据的长度
                $post_str .= $_post."\r\n\r\n "; //传递POST数据
                $header .= $post_str;
        }
        fwrite($fp, $header);
        //echo fread($fp, 1024); //我们不关心服务器返回
        fclose($fp);
        return true;
}
Jetzt können Sie über diese

Funktion die Ausführung eines PHP-Skripts auslösen, woraufhin die Funktion zurückkehrt. Anschließend können wir mit dem nächsten Schritt fortfahren.

Ein weiteres Problem besteht darin, dass der Client die Verbindung trennt. Das heißt, die Verbindung wird unmittelbar nach dem Senden der Anforderung durch triggerRequest geschlossen, was dazu führen kann, dass das auf dem Server ausgeführte Skript beendet wird.

Innerhalb von PHP behält das System den Verbindungs-

Status bei, der drei mögliche Zustände hat:

* 0 – NORMAL (normal)

* 1 - ABORTED (abnormaler Exit)

* 2 - TIMEOUT (Timeout)

Wenn das PHP-Skript normal im NORMAL-Zustand ausgeführt wird, ist die Verbindung gültig. Wenn der Client die Verbindung trennt, wird das Statusflag ABORTED aktiviert. Eine Unterbrechung der Remote-Client-Verbindung wird normalerweise dadurch verursacht, dass der Benutzer auf die Schaltfläche S

TOP klickt. Wenn die Verbindungszeit das Zeitlimit von PHP überschreitet (siehe Funktion set_time_limit()), wird das Flag für den TIMEOUT-Status aktiviert.

Sie können entscheiden, ob das Skript beendet werden muss, wenn der Client die Verbindung trennt. Manchmal ist es praktisch, ein Skript vollständig ausführen zu lassen, auch wenn kein Remote-Browser die Ausgabe des Skripts akzeptiert. Standardmäßig wird das Skript beendet, wenn die Remote-Client-Verbindung unterbrochen wird. Diese Verarbeitung kann durch „ignore_user_abort“ in php.ini oder durch die entsprechenden „php_value“-Funktionen „ignore_user_abort“ und „ignore_user_abort()“ in den Apache-.conf-Einstellungen gesteuert werden. Wenn PHP nicht angewiesen wird, Benutzerunterbrechungen zu ignorieren, wird das Skript unterbrochen, es sei denn über register_shutdown_function() Die Shutdown-Trigger-Funktion ist eingestellt. Wenn der Remote-Benutzer auf die Schaltfläche „STOP“ klickt und das Skript erneut versucht, Daten auszugeben, erkennt PHP über diese Schließtriggerfunktion, dass die Verbindung unterbrochen wurde, und ruft die Schließtriggerfunktion auf.

Skripte können auch durch den integrierten Skript-Timer unterbrochen werden. Das Standard-Timeout-Limit beträgt 30 Sekunden. Dieser Wert kann durch Festlegen von max_execution_time in php.ini oder dem entsprechenden Parameter „php_value max_execution_time“ in den Apache .conf-Einstellungen oder der Funktion set_time_limit() geändert werden. Wenn der Zähler abläuft, wird das Skript ähnlich wie in der oben genannten Verbindungsunterbrechungssituation beendet und die zuvor registrierte Auslöserfunktion zum Herunterfahren wird zu diesem Zeitpunkt ebenfalls ausgeführt. In der Shutdown-Trigger-Funktion können Sie durch Aufrufen der Funktion „connection_status()“ überprüfen, ob das Timeout dazu geführt hat, dass die Shutdown-Trigger-Funktion aufgerufen wurde. Wenn eine Zeitüberschreitung zu einem Aufruf der das Herunterfahren auslösenden Funktion führt, kehrt die Funktion zurück 2.

Zu beachten ist, dass die Zustände ABORTED und TIMEOUT gleichzeitig gültig sein können. Dies ist möglich, wenn PHP angewiesen wird, Benutzer-Exit-Aktionen zu ignorieren. PHP wird weiterhin bemerken, dass der Benutzer die Verbindung getrennt hat, das Skript jedoch weiterhin ausgeführt wird. Bei Erreichen des Laufzeitlimits wird das Skript beendet und die eingestellte Shutdown-Trigger-Funktion ebenfalls ausgeführt. An dieser Stelle werden Sie feststellen, dass die Funktion „connection_status()“ den Wert 3 zurückgibt.

      所以还在要触发的脚本中指明:

ignore_user_abort(TRUE); //如果客户端断开连接,不会引起脚本
abort.set_time_limit(0);//取消脚本执行延时上限

     或者,也可以使用:

register_shutdown_function(callback fuction[, parameters]);//注册脚本退出时执行的函数

Das obige ist der detaillierte Inhalt vonCodebeispiel für die Verwendung von fscok zur Implementierung eines asynchronen Aufrufs von PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn