views:

454

answers:

3

I have a PHP redirect page to track clicks on links. Basically it does:

 - get url from $_GET
 - connect to database
 - create row for url, or update with 1 hit if it exists
 - redirect browser to url using Location: header

I was wondering if it's possible to send the redirect to the client first, so it can get on with it's job, and then log the click. Would simply switching things around work?

+1  A: 

Most databases give you the ability to insert a query delayed, so it'll only process when the database is idle. You're most likely best doing that...so long as the data isn't critical (you'll lose the query if mysqld dies or the RAM is flushed). http://dev.mysql.com/doc/refman/5.1/en/insert-delayed.html

Adam Gibbins
+4  A: 

You can do this:

  1. get url from $_GET
  2. send Location: header
  3. call flush()
  4. connect to database
  5. create row for url, or update with 1 hit if it exists

This will not necessarily cause the browser to go on its way immediately, since your connection is still being held open and what the browser does about that is up to it, but (barring conditions that cause flush() to not work) it will at least get the Location: header out to the browser so it can do the redirect if it likes.

If that's not good enough, I'd recommend dumping your data to per-minute or per-second files that a script then picks up for postprocessing into the database. If that's not good enough, you can play with pcntl_fork(); this is an extremely hairy thing to do under Apache SAPI.

chaos
A: 

That is fine. PHP will finish executing before flushing the redirect header to the client. If you still have doubts try saving this in a file and loading from browser:

<?php
header('location: /');
sleep(2);
?>

The redirect should not happen for 2 seconds.

aleemb