Hi,
I’ve written a PHP script which connects to a server, fetches data, creates an XML file from the data, and sends it back to the client. I cache the file and only update it in a request if the cached file is 2 hours old. Otherwise, the current XML file is output and no connection to the server is made.
If the cache is old, this means that the response takes several seconds to complete. A better approach would be to output the existing XML file to the user, close the connection and then rebuild the XML file. Then the client would receive the ‘old’ version directly, while the next request will receive the ‘new’ version. Note that this means that the response must be sent to the client, and then the script must continue to rebuild the XML file.
In PHP there is the ‘die’ function, which causes the response to be sent directly, but the script is also stopped. I need some function which finalizes and sends the response just like die does, but does not stop the script from being executed.
Is it possible at all to do this?
You can try using the Flush() function, but I think a better solution is in order.
Rather than updating on a request, which isn’t a great idea, run a cron job every 2 hours or so instead. This will update the XML file. Send the user this file - if it’s before an update they see an old cache, after the update they see a new one. It’s similar to your idea, but the time of update isn’t related to them requesting the page.
One thing to be careful of is sending the file to the user if the update is in process - whilst unlikely, it’s possible. So instead of rewriting the original cache file from the beginning, write a temporary file first, then replace the original.
There is a function in php that does exactly what you looking for but only if php is setup as fastcgi and controlled by php-fpm:
fastcgi_finish_request()
The blueprint for using it would be something like this:
- get contents of you cache file
echo $contents
fastcgi_finish_request();
- now check file creation time,
if older than 2 hours, recreate it. The contents of existing file
are already sent to the browser by now, so it does not matter if this step
takes long, your client is already reading the file and does not know that
your script is working overtime.