views:

260

answers:

3

I have a website which works with PHP on the server side.

Users access pages and PHP does some calculations, writes data to a MySQL database etc.

Imagine a user accesses a page where PHP creates an account for the user. The creation consists of two parts: inserting the registration data into the table "users" and inserting settings for this account into the table "settings". These are two SQL queries which have to be executed one after another. If the user quits the page after the first query, there aren't any values inserted into "settings".

How could I avoid this issue? I think simply by using ignore_user_abort(true), right?

So isn't it useful to call ignore_user_abort(true) on the top of every PHP script? I don't know any cases where it should cause problems.

+2  A: 

If you need multiple queries to either happen completely or not at all, then you should be doing it properly using transactions instead of putting a bandage on the problem.

It can be handy for the remote side to abort a request if e.g. the request involves lengthy calculations and the user decides that they don't need the results after all.

Ignacio Vazquez-Abrams
+1  A: 

You can set ignore_user_abort in php.ini: PHP.ini configuration

I wouldn't do this, though. I would much rather have the PHP page start another PHP instance on the command line that does the querying in the background, e.g. using exec.

Also, it could be that your basic flow concept is skewed. If the user aborts the execution of a calculation, you should probably roll it back properly anyway - but that depends on the nature of what is being done.

Pekka
+2  A: 

For your specific example, using database transactions (as mentioned by Ignacio) would be the more suitable approach.

There are other cases where you might want to make sure the user can't abort early, though, not relating to databases. For example, if you update the database and then send out a mail, you don't want a user to be able to stop the process before the mail goes out. In this sort of case, ignore_user_abort would be appropriate.

However, note that a broken pipe due to client aborting the connection doesn't stop execution right away, only at the point you next try to write to the script output. This can be through calling echo or print, or even just by closing the PHP tag and inserting some whitespace before opening a new one (... ?> <?php ...). So if you have all the ‘action’ part of your script at the top of the page, before you try to write any page content, you don't have to worry about interruptions from broken pipes affecting your app logic.

And of course you should be separating action logic from page content in that way anyway.

bobince