The web server executes a script, which may be completed in a few milliseconds or may not be completed in several minutes. If the program executes slowly, the user may not have the patience to wait any longer and close the browser.
Sometimes, we don’t even care about the execution results of these time-consuming scripts, but we have to wait for them to finish executing and return before we can continue to the next step.
So is there any way to simply trigger the call of these time-consuming scripts and then continue to the next step, so that these time-consuming scripts can be executed slowly on the server side?
Next, I will use fscokopen to implement this function.
PHP supports socketprogramming, which is fsockopen. When I was doing CMS before, I also used it for SMTP sending.
fscokopen returns a handle to the remote host connection. You can perform fwrite, readfgets,freadand other operations on her just like using the handle returned byfopen.
The main desired effect of our asynchronous PHP is to trigger a PHP script and then return immediately, leaving it to execute slowly on the server side. I also wrote an article discussing this issue before.
Then, we can use fsockopen to connect to the local server, trigger script execution, and then return immediately without waiting for the script execution to complete.
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; }
Now, you can trigger the execution of a PHP script through thisfunction, and then the function will return. We can then proceed to the next step.
Another problem is that when the client disconnects. That is, the connection is closed immediately after triggerRequest sends the request, which may cause the script being executed on the server to exit.
Within PHP, the system maintains the connectionstatus, which has three possible states:
* 0 – NORMAL (normal)
* 1 – ABORTED (abnormal exit)
* 2 – TIMEOUT (timeout)
When the PHP script runs normally in the NORMAL state, the connection is valid. When the client disconnects, the ABORTED status flag will be turned on. Interruption of the remote client connection is usually caused by the user clicking the STOPbutton. When the connection time exceeds PHP's time limit (seeset_time_limit() function), the flag for the TIMEOUT state will be turned on.
You can decide whether the script needs to exit when the client disconnects. Sometimes it is convenient to have a script run completely, even if no remote browser accepts the script's output. The default is for the script to exit when the remote client connection is lost. This processing can be controlled by ignore_user_abort in php.ini or by the corresponding "php_value ignore_user_abort" and ignore_user_abort() functions in the Apache .conf settings. If PHP is not told to ignore user interruptions, the script will be interrupted unless via register_shutdown_function() The shutdown trigger function is set. Through this close trigger function, when the remote user clicks the STOP button and the script tries to output data again, PHP will detect that the connection has been interrupted and call the close trigger function.
Scripts may also be interrupted by the built-in script timer. The default timeout limit is 30 seconds. This value can be changed by setting max_execution_time in php.ini or the corresponding "php_value max_execution_time" parameter in the Apache .conf settings or the set_time_limit() function. When the counter times out, the script will exit similar to the above connection interruption situation, and the previously registered shutdown trigger function will also be executed at this time. In the shutdown trigger function, you can check whether the timeout caused the shutdown trigger function to be called by calling the connection_status() function. If a timeout results in a call to the shutdown triggering function, the function will return 2.
One thing to note is that the ABORTED and TIMEOUT states can be valid at the same time. This is possible when telling PHP to ignore user exit actions. PHP will still notice that the user has disconnected but the script is still running. If the running time limit is reached, the script will be exited and the set shutdown trigger function will also be executed. At this point you will find that the function connection_status() returns 3.
所以还在要触发的脚本中指明:
ignore_user_abort(TRUE); //如果客户端断开连接,不会引起脚本 abort.set_time_limit(0);//取消脚本执行延时上限
或者,也可以使用:
register_shutdown_function(callback fuction[, parameters]);//注册脚本退出时执行的函数
The above is the detailed content of Code example of how to use fscok to implement asynchronous call to PHP. For more information, please follow other related articles on the PHP Chinese website!