放弃PHP中的长进程(但让它们完成)

时间:2009-03-08 02:10:25

标签: php scripting

我有一个HTML表单,提交到启动脚本的PHP页面。该脚本可能需要3秒到30秒才能运行 - 用户无需四处寻找此脚本即可完成。

是否有可能启动PHP脚本,立即打印“谢谢”给用户(或其他任何东西)并让他们在你的脚本继续工作的同时继续他们的快乐方式?

在我的特定情况下,我将表单数据发送到php脚本,然后将数据发布到许多其他位置。等待所有帖子成功,目前不符合我的利益。我只想让脚本运行,允许用户去做他们喜欢的任何其他事情,就是这样。

6 个答案:

答案 0 :(得分:2)

将您的长期工作放在另一个PHP脚本中,例如

background.php:

sleep(10);
file_put_contents('foo.txt',mktime());

foreground.php

$unused_but_required = array();
proc_close(proc_open ("php background.php &", array(), $unused_but_required));
echo("Done);

您将立即看到“完成”,文件将在10秒后写入。

我认为proc_close有效,因为我们给proc_open没有管道,也没有文件描述符。

答案 1 :(得分:1)

在脚本中,您可以设置:

<?php
 ignore_user_abort(true);

这样,当用户离开页面时,脚本不会终止。但是在组合这个whith时要非常小心

 set_time_limit(0);

此后脚本可以永久执行。

答案 2 :(得分:1)

您可以使用set_time_limitignore_user_abort,但一般来说,我建议您将作业放入队列并使用异步脚本来处理它。这是一种更简单耐用的设计。

答案 3 :(得分:0)

您可以尝试使用flush及相关的输出缓冲区函数立即将缓冲区中的内容发送到浏览器:

答案 4 :(得分:0)

Theres是一个名为php_fork的pcntl_fork()的API包装器。

但是,这个问题出现在Daily WTF上......不要用玻璃瓶敲钉子。

答案 5 :(得分:0)

我最终得到了以下内容。

<?php

  // Ignore User-Requests to Abort
  ignore_user_abort(true);
  // Maximum Execution Time In Seconds
  set_time_limit(30);

  header("Content-Length: 0");
  flush();

  /*

    Loooooooong process

  */

?>