views:

167

answers:

3

Hi

I have a very similar setup to the person here:
http://stackoverflow.com/questions/265073/php-background-processes
i.e a very long script that takes up to 10 minutes. However, I need the person who calls the script redirected back to the homepage while the script works. In other words, I need the user experience to be something like this:

  • click the update button
  • script begins to execute, can take up to 10 minutes
  • user is redirected back to the home page immediately

Is this possible using only PHP? I gather I will need

ignore_user_abort(true); 
set_time_limit(0);

But how do I redirect the user? I can't use javascript because output only gets written to the page at long increments, and I want the redirection to be immediate. Can I use headers? Or will that mess with things?

Alternatively, I could use the cron job approach, but I have zero experience in making a cron job or having it run php code (is that even possible?)

Thanks,
Mala

Update:
Using headers to redirect does not work - the page will not load until the script is done. However, eventually the webserver times out and says "Zero-Sized Reply: The requested URL could not be retrieved" (although the script continues running). I guess my only option is to go with the cron job idea. Ick!

A: 

Why not try the header approach and see what happens? You could also try a call to php header method and see if this does the trick. I would work on trial and error to see what will solve your problem.

Toby Allen
+1  A: 

I've tried several methods and none seems to work, I've even tried to use register_shutdown_function() but that also failed. I guess you're stuck with making a cron job.

I just remembered something (but I haven't tested it), you can try to do something like this:

set_time_limit(0);
ignore_user_abort(true);

ob_start(); // not sure if this is needed

// meta refresh or javascript redirect

ob_flush(); // not sure if this is needed
flush();

// code to process here

exit();

Not sure if it'll work but you can try it out.

Alix Axel
Thanks. I want to avoid "soft" redirects if at all possible, so I suppose I'm off to make a cron job! How would you suggest doing it? Have a cron job run a "Script manager" type script, or just directly run the godawful update script?
Mala
I'm not sure if I fully understand you, but before you go into CRON jobs I think you should try Cassy's solution since both method use need the same requirements.
Alix Axel
Also, have you considered AJAX as an option? The user clicks something, a PHP page is processed in the background and upon completion you could have a "job done" message show up on the webpage.
Alix Axel
+2  A: 

The most obvious solution to me would be splitting the redirect and the background calculation in two separate files and let the redirect script execute the 10-minute script:

job.php:

<?php
// do the nasty calculation here

redirect.php:

<?php
// start the script and redirect output of the script to nirvana, so that it
// runs in the background
exec ('php /path/to/your/script/job.php >> /dev/null 2>&1 &'); 

// now the redirect
header ('Location /index.php');

Assumptions for this to work: You should be on a Linux host with either safe_mode disabled or having set the safe_mode_exec_dir appropriately. When you're running under windows, the exec string needs to be adapted, while the rest about safe_mode remains true.

Notice: When you need to pass arguments to the script, use escapeshellarg() before passing it on, see also the PHP manual on exec

Cassy