开发者

ignore_user_abort and redirect in php?

I have a very similar setup to the person here:

PHP Background Processes

i.e a very long script that takes up to 10 min开发者_开发知识库utes. 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!


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


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.


I have a similar situation with processing logins. To keep it short... I get a PDT, IPN and each sends me a logging email. An email is sent to client on IPN VERIFIED to give serial number and password to client. As PDT and IPN I use goto to send me a logging email instead of a bunch of sequential ifs. On reading many answers I studied each to figure what would suit my isssue. I finally used...

<?php
  ignore_user_abort(TRUE); // at very top

As I worked through the progressive checks (no ifs), if they failed I use for example...

  $mcalmsg .= "Check [serialnbr]\r\n";
  if (empty($_POST['serialnbr']))
    {    header('Location: '.$returnurl.'?error=1');
      $mcalmsg .= "Missing [serialnbr]\r\n";
      goto mcal_email; // Last process at end of script        
    }
    else
    {$serialnbr=strtoupper(htmlspecialchars(trim($_POST['serialnbr'])));
     $mcalmsg .= "[serialnbr]=$serialnbr\r\n";
    }

This (so far) is working just as needed. Of course there is more in the script but follows the same concept. Where this says location, there are also 3 information pages that can each be displyed using the same concept.

mcal_email: //last process before ending, always gets here after all else from goto or clearing all checks.
 // compose email and send
?> // end of script


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜