September 20, 2010 by Ivan Kristianto
Keep PHP Process Upon Closed Client Connection
PHP process as default will stop or terminate the process when the client close the connection or process timeout. When user stop the process through browser it will automatically send abort header, and PHP will turn on the abort flag, so the process the currently running will be force to stop. As well as the process timeout met, the PHP will eventually stop the process too.
I had one case that i should fire another script with Curl library in PHP. But since the other script took a very long time to finish, the main PHP process will keep waiting until that process finish and return the value or it will meet the timeout. I try to find something that can run curl asynchronously, but seems like didn’t work either. If i set the timeout too short, it will terminate the other script process so it won’t finish.
So basically i’m running a script, which will fire another script but the main script won’t waiting (close the connection as soon as the other scipt fired), but the process on the other script will keep running on background until it is finished. It took me a while to solve this, and i want to personally thanks seoforall from DigitalPoint forum for pointing me out.
So the key to solve this is ignore_user_abort and output buffering. So when the the script is fired, it will keep running when curl is closed or user abort. See the example below:
ob_end_clean(); header("Connection: close\r\n"); header("Content-Encoding: none\r\n"); ignore_user_abort(true); // optional set_time_limit(0); // run script until it finish 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, you can use whether curl or file_get_content:
$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 called the main script which is call another script using curl, it won’t interfere the main script process or make the main process waiting. But the other script will keep running on background process until it is finished. You can imagine it like 2 different process running asynchronously which one process is called by the other process.
More details about PHP connection handling.