php中的ignore_user_abort和重定向?

发布于 2024-08-15 05:33:09 字数 656 浏览 3 评论 0原文

我的设置与这里的人非常相似:
PHP 后台进程
即一个非常长的脚本,最多需要 10 分钟。但是,我需要在脚本运行时将调用脚本的人重定向回主页。换句话说,我需要的用户体验是这样的:

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

这仅使用 PHP 可能吗?我想我需要

ignore_user_abort(true); 
set_time_limit(0);

但是如何重定向用户?我无法使用 javascript,因为输出只会以长增量写入页面,并且我希望立即重定向。我可以使用标头吗?或者这会弄乱事情吗?

或者,我可以使用 cron 作业方法,但我在制作 cron 作业或让它运行 php 代码方面经验为零(这可能吗?)

谢谢,
马拉

更新:
使用标头进行重定向不起作用 - 在脚本完成之前页面不会加载。然而,最终网络服务器超时并显示“零大小回复:无法检索所请求的 URL”(尽管脚本继续运行)。我想我唯一的选择就是采用 cron job 的想法。恶心!

I have a very similar setup to the person here:
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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清晨说晚安 2024-08-22 05:33:09

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

job.php:

<?php
// do the nasty calculation here

redirect.php:< /strong>

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

假设:您应该在 Linux 主机上禁用 safe_mode 或已正确设置 safe_mode_exec_dir。当您在 Windows 下运行时,需要调整 exec 字符串,而有关 safe_mode 的其余部分保持不变。

注意:当您需要向脚本传递参数时,请在传递之前使用escapeshellarg(),另请参阅关于 exec 的 PHP 手册

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

棒棒糖 2024-08-22 05:33:09

我尝试了几种方法,但似乎都不起作用,我什至尝试使用 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();

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

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.

青春有你 2024-08-22 05:33:09

我在处理登录时也遇到类似的情况。
为了保持简短...
我收到 PDT、IPN,每个都向我发送一封日志电子邮件。
通过 IPN VERIFIED 向客户发送一封电子邮件,向客户提供序列号和密码。
作为 PDT 和 IPN,我使用 goto 向我发送一封日志电子邮件,而不是一堆连续的 if。
在阅读了许多答案后,我研究了每个答案,以找出适合我的问题的答案。
我最终使用...

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

当我进行渐进检查(没有如果)时,如果它们失败,我使用例如...

  $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

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
会发光的星星闪亮亮i 2024-08-22 05:33:09

为什么不尝试 header 方法并看看会发生什么?您还可以尝试调用 php header 方法,看看这是否有效。我会进行反复试验,看看什么可以解决您的问题。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文