Strangely enough, I find myself doing actual work-type programming
February 14, 2010 1:26 PM   Subscribe

What happens to my php script if the user exits the browser before it's done?

I have a php form served by apache that updates some records in a mysql database. If the database grows, it is conceivable that the update might take a significant amount of time to finish. What happens if the user exits their browser before the update is complete? Will apache kill the script or is it guaranteed to run to the end?

Does it matter if I submit the form as a straight POST request or via the prototype.js AJAX framework?

Also, what happens if the browser times out while waiting for the page to load?
posted by Dr Dracator to Computers & Internet (9 answers total) 2 users marked this as a favorite
 
Best answer: Once the PHP script is invoked on the server, it'll run until it finishes, regardless of what happens with the browser. It doesn't matter if it goes by clicking a link, submitting a form, or sending an AJAX request--it's all HTTP GET/POST.

If you're submitting a lot of data in the POST, and the browser is closed before the data is all sent by the browser, then you'll get truncated data. But if the cause of slowness is the database running behind, then as long as Apache receives the entire request, the PHP script will execute in its entirety. All you'll be missing is the response from the script saying "done".

Note that if the database is slow, there might be a timeout between the database and the Apache process executing the script.
posted by fatbird at 1:50 PM on February 14, 2010 [1 favorite]


Best answer: If your script is taking that long you should redesign it.

But to answer your question...

Your script will probably hit the max execution time. If it doesn't then it will complete.
If a user closes their browser the script will keep running.

You can easily test this:

<>
echo "Sleeping...";
sleep(60);
touch("/tmp/sleep-test.txt");

?>

To test this, close your browser when you see the text "Sleeping...", then check for the file /tmp/sleep-test.txt after a minute.
posted by devnull at 1:57 PM on February 14, 2010


As everyone else said, the PHP will continue running.

I know it's not the same language, but in Perl if you try to send some text to the browser when the user has closed the window or navigated away then you'll get a SIGPIPE.

Normally this is just ignored and the text disappears into the ether - but you may wish to catch this with pcntl_signal(SIGPIPE, "my_signal_handler") and then do something special within the my_signal_handler function.
posted by mr_silver at 2:40 PM on February 14, 2010


The script keeps running until it completes or exceeds the max_execution_time defined in php.ini, whichever comes first. (You can override the time limit with set_time_limit(). You can pass a value of zero to eliminate the time limit entirely, but then your scripts will run forever if they hit an infinite loop or other non-terminating condition. Restart Apache if this happens.)
posted by ixohoxi at 4:04 PM on February 14, 2010


Response by poster: Thanks for the answers everybody. Some comments:

Note that if the database is slow, there might be a timeout between the database and the Apache process executing the script.

Isn't this covered by max_execution_time? I found it's been set to 5000 already, which should be more than enough.

If your script is taking that long you should redesign it.

It is essentially a loop running pairs of select/insert queries, I don't know how it could be rewritten to be any faster. Execution time is not a problem for now, I'm just trying to be defensive in case this thing stays up and running for the next 20 years and nobody bothers to clear out the db ever.
posted by Dr Dracator at 10:21 PM on February 14, 2010


I don't know how it could be rewritten to be any faster.

Are you opening and closing the database connection inside the loop? Common mistake, and very expensive. Batch your queries and do them with a single db connection, you'll see a hundredfold increase in speed.
posted by ook at 7:30 AM on February 15, 2010


It is essentially a loop running pairs of select/insert queries, I don't know how it could be rewritten to be any faster.

Just as an example of rewriting: if it's your selects which are slow here, and you're just checking if something exists in the DB, perhaps matching what you're going to insert, you could run a single select with all the necessary lookup values before your loop thus reducing N selects to 1.
posted by beerbajay at 7:31 AM on February 15, 2010


It is essentially a loop running pairs of select/insert queries, I don't know how it could be rewritten to be any faster.

One thing that can cut down on the chances on the browser or surfer giving up on your page, is flushing the output from time to time as the page is processing. That means sending all the output that the page has generated so far to the browser, and then telling it that more is on the way. I don't know PHP, but I'm certain there's a way to do this. Here's a pseudo-code example of how to do this in a loop:
if(loopCounter % 5 == 0)
{
    output.write(loopCounter + " records processed. Processing continues...");
    output.flush();
}
This will of course not compile in any language, but I think you get the idea. As long as data trickles in this way, the browser won't give up loading, and the user will see the updates and (hopefully) not close the browser. If you're feeling adventurous, you could come up with something more elaborate and graphically pleasing using Javascript.
posted by Vorteks at 8:55 AM on February 15, 2010


Also, considering using precompiled/parameterized queries when running in a loop. I assume PHP supports them.
posted by Vorteks at 8:57 AM on February 15, 2010


« Older How much to pay for someone to shovel snow off the...   |   Making my own sheet music--how to add in chords? Newer »
This thread is closed to new comments.