I'm attempting to do an AJAX call (via JQuery) that will initiate a fairly long process. I'd like the script to simply send a response indicating that the process has started, but JQuery won't return the response until the PHP script is done running.
I've tried this with a "close" header (below), and also with output buffering; neither seems to work. Any guesses? or is this something I need to do in JQuery?
<?php echo( "We'll email you as soon as this is done." ); header( "Connection: Close" ); // do some stuff that will take a while mail( '[email protected]', "okay I'm done", 'Yup, all done.' ); ?>
Closes the connection to the database.
HTTP/1.1 defines the "close" connection option for the sender to. signal that the connection will be closed after completion of the. response. For example, Connection: close. in either the request or the response header fields indicates that the connection SHOULD NOT be considered `persistent' (section 8.1)
In HTTP 1.0, the server always closes the connection after sending the response UNLESS the client sent a Connection: keep-alive request header and the server sent a Connection: keep-alive response header. If no such response header exists, the client must close its end of the connection after receiving the response.
Any HTTP client, server, or proxy can close a TCP transport connection at any time. The connections normally are closed at the end of a message, but during error conditions, the connection may be closed in the middle of a header line or in other strange places.
The following PHP manual page (incl. user-notes) suggests multiple instructions on how to close the TCP connection to the browser without ending the PHP script:
Supposedly it requires a bit more than sending a close header.
OP then confirms: yup, this did the trick: pointing to user-note #71172 (Nov 2006) copied here:
Closing the users browser connection whilst keeping your php script running has been an issue since [PHP] 4.1, when the behaviour of
register_shutdown_function()
was modified so that it would not automatically close the users connection.sts at mail dot xubion dot hu Posted the original solution:
<?php header("Connection: close"); ob_start(); phpinfo(); $size = ob_get_length(); header("Content-Length: $size"); ob_end_flush(); flush(); sleep(13); error_log("do something in the background"); ?>
Which works fine until you substitute
phpinfo()
forecho('text I want user to see');
in which case the headers are never sent!The solution is to explicitly turn off output buffering and clear the buffer prior to sending your header information. Example:
<?php ob_end_clean(); header("Connection: close"); ignore_user_abort(true); // just to be safe ob_start(); echo('Text the user will see'); $size = ob_get_length(); header("Content-Length: $size"); ob_end_flush(); // Strange behaviour, will not work flush(); // Unless both are called ! // Do processing here sleep(30); echo('Text user will never see'); ?>
Just spent 3 hours trying to figure this one out, hope it helps someone :)
Tested in:
- IE 7.5730.11
- Mozilla Firefox 1.81
Later on in July 2010 in a related answer Arctic Fire then linked two further user-notes that were-follow-ups to the one above:
It's necessary to send these 2 headers:
Connection: close Content-Length: n (n = size of output in bytes )
Since you need know the size of your output, you'll need to buffer your output, then flush it to the browser:
// buffer all upcoming output ob_start(); echo 'We\'ll email you as soon as this is done.'; // get the size of the output $size = ob_get_length(); // send headers to tell the browser to close the connection header('Content-Length: '.$size); header('Connection: close'); // flush all output ob_end_flush(); ob_flush(); flush(); // if you're using sessions, this prevents subsequent requests // from hanging while the background process executes if (session_id()) {session_write_close();} /******** background process starts here ********/
Also, if your web server is using automatic gzip compression on the output (ie. Apache with mod_deflate), this won't work because actual size of the output is changed, and the Content-Length is no longer accurate. Disable gzip compression the particular script.
For more details, visit http://www.zulius.com/how-to/close-browser-connection-continue-execution
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With