在php中ignore_user_abort和重定向?

时间:2009-12-13 08:27:37

标签: php process background

我对这个人的设置非常相似:
PHP Background Processes
即一个非常长的脚本,最多需要10分钟。但是,我需要在脚本工作时调用脚本的人重定向回主页。换句话说,我需要用户体验是这样的:

  • 点击更新按钮
  • 脚本开始执行,最多可能需要10分钟
  • 用户立即重定向回主页

这只能使用PHP吗?我知道我需要

ignore_user_abort(true); 
set_time_limit(0);

但是如何重定向用户?我不能使用javascript,因为输出只会以很高的增量写入页面,我希望重定向是立即的。我可以使用标题吗?或者那会弄得一团糟吗?

或者,我可以使用cron job方法,但是我没有做过cron工作或运行php代码的经验(甚至可能吗?)

谢谢,
马拉

更新
使用标头重定向不起作用 - 在脚本完成之前,页面将不会加载。但是,最终网络服务器超时并说“零大小的回复:无法检索到请求的URL”(尽管脚本继续运行)。我想我唯一的选择就是遵循cron的工作理念。伊克!

4 个答案:

答案 0 :(得分:2)

对我来说最明显的解决方案是将重定向和后台计算分成两个单独的文件,并让重定向脚本执行10分钟的脚本:

<强> 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');

此操作的假设:您应该在禁用safe_mode或已正确设置safe_mode_exec_dir的Linux主机上。当你在windows下运行时,需要调整exec字符串,而其余的safe_mode仍然是正确的。

注意:当您需要将参数传递给脚本时,请在传递之前使用escapeshellarg(),另请参阅PHP manual on exec

答案 1 :(得分:1)

我尝试了几种方法,似乎没有一种方法可行,我甚至试图使用register_shutdown_function(),但也失败了。我猜你一直在做一个cron工作。

我只记得一些事情(但我没有测试过),你可以尝试这样做:

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();

不确定它是否有效,但你可以尝试一下。

答案 2 :(得分:0)

我处理登录的情况类似。 保持简短...... 我得到了一个PDT,IPN,每个人都给我发了一封记录电子邮件。 在IPN VERIFIED上向客户端发送电子邮件,以向客户端提供序列号和密码。 作为PDT和IPN,我使用goto向我发送日志邮件而不是一堆顺序ifs。 在阅读许多答案时,我研究了每个答案以找出适合我的问题的答案。 我终于用了......

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

当我通过渐进式检查(没有ifs)时,如果他们失败我会使用例如......

  $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";
    }

这(到目前为止)正在按需工作。 当然,脚本中有更多内容,但遵循相同的概念。 如果这是位置,那么还有3个信息页面,每个信息页面都可以使用相同的概念进行显示。

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

答案 3 :(得分:-1)

为什么不试试标题方法,看看会发生什么?你也可以尝试调用php header方法,看看这是否有效。我会尝试试错,看看什么能解决你的问题。