PHP processes will by default stop or terminate when the client closes the connection or a process timeout occurs. When a user stops the process through the browser it will automatically send an abort header, and PHP will turn on the abort flag, so the currently running process will be forced to stop. Similarly when the process timeout is reached, PHP will eventually stop the process too.
I had one case where I needed to fire another script with the Curl library in PHP. But since the other script took a very long time to finish, the main PHP process would keep waiting until that process finished and returned a value, or it would meet the timeout. I tried to find something that could run curl asynchronously, but that didn’t seem to work either. If I set the timeout too short, it would terminate the other script’s process so it wouldn’t finish.
So basically I’m running a script that will fire another script, but the main script won’t wait (it closes the connection as soon as the other script is fired), while the process on the other script keeps running in the background until it is finished. It took me a while to solve this, and I want to personally thank seoforall from DigitalPoint forum for pointing me in the right direction.
The key to solving this is ignore_user_abort and output buffering. When the script is fired, it will keep running when curl is closed or the user aborts. See the example below:
ob_end_clean();
header("Connection: closern");
header("Content-Encoding: nonern");
ignore_user_abort(true); // optional
set_time_limit(0); // run script until it finishes
ob_start();
echo ('Text user will see');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Strange behaviour, will not work
flush(); // Unless both are called !
ob_end_clean();
// Run your main process here
So I just make another script to call it via HTTP request, using either curl or file_get_contents:
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, 'path/to/your/script';
curl_setopt ($ch, CURLOPT_TIMEOUT, 1);
curl_setopt ($ch, CURLOPT_POST, true);
curl_setopt ($ch, CURLOPT_FRESH_CONNECT, true);
curl_exec ($ch);
curl_close($ch);
So when I call the main script which calls another script using curl, it won’t interfere with the main script process or make the main process wait. But the other script will keep running as a background process until it is finished. You can think of it as 2 different processes running asynchronously, where one process is called by the other.
More details about PHP connection handling.
