- URL: https://www.laruence.com/en/2008/04/14/318.html
- Please include attribution when republishing.
Browsers and servers communicate over the HTTP protocol. This is a protocol based on a request-and-response model. The browser issues a request to the server via a URL, the web server receives the request, executes some program, then responds by sending the corresponding HTML code back to the client.
This creates a problem: the program the web server executes might finish in a few milliseconds, or might not finish even after several minutes. If the program runs slowly, the user may lose patience and just close the browser.
And sometimes we don't care at all about the return value of these time-consuming scripts, yet we still have to wait for them to finish and return before we can proceed to the next step.
So is there a way to simply trigger these time-consuming scripts and then move on to the next step, letting the scripts run slowly on the server side?
After experimenting, I've summarized several methods to share with you:
1. The simplest approach is to embed an AJAX call in the HTML code returned to the client, or embed an img tag whose src points to the time-consuming script you want to execute.
This method is the simplest and the fastest. The server side doesn't need to make any call at all.
But the drawback is that Ajax should generally be triggered after onLoad — that is, if the user opens the page and then closes it, our background script never gets triggered.
With the img tag approach, this can't really be called asynchronous execution in the strict sense. The user's browser will wait a long time for the PHP script to finish, meaning the browser's status bar keeps showing that it's still loading.
Of course, you can also use other methods based on the same principle, such as a script tag, etc.
2. popen()
resource popen ( string command, string mode );
//Opens a pipe to a process, which is created by forking and executing the given command.
So you can call it while ignoring its output.
pclose(popen("/home/xinchen/backend.php &", 'r'));
This method avoids the drawback of the first method, and it's also fast. The problem, though, is that it can't request another WebService over HTTP — it can only execute a local script file. It can also only be opened one-way, so you can't pass a lot of parameters to the called script.
And if traffic is very high, it will spawn a large number of processes. If external resources are involved, you also have to handle contention yourself.
3. Using CURL
With this method, set CURLOPT_TIMEOUT to 1 (1 is the minimum — annoying). That is, the client has to wait at least 1 second.
$ch = curl_init();
$curl_opt = array(CURLOPT_URL, 'http://www.example.com/backend.php',
CURLOPT_RETURNTRANSFER, 1,
CURLOPT_TIMEOUT, 1,);
curl_setopt_array($ch, $curl_opt);
curl_exec($ch);
curl_close($ch);
4. Using fsockopen
This method should be the most perfect one, but the drawback is that you have to assemble the HTTP header part yourself.
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET /backend.php / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
/*ignore the result
while (!feof($fp)) {
echo fgets($fp, 128);
}*/
fclose($fp);
}
So overall, the easiest and simplest to use is still the first method.
The most perfect should be the last one, but it's more complex.
If you have a better approach, discussion is welcome.
Be First to Comment