4

任何人都知道如何关闭连接(除了flush()?),但之后继续执行一些代码。

我不希望客户看到页面完成后可能发生的漫长过程。

4

5 回答 5

9

您可能想查看pcntl_fork()- 它允许您分叉当前脚本并在单独的线程中运行它。

我在一个项目中使用它,用户上传文件,然后脚本对其执行各种操作,包括与第三方服务器通信,这可能需要很长时间。初始上传后,脚本分叉并向用户显示下一页,然后父进程自行关闭。然后子进程继续执行,并由返回的页面使用 AJAX 查询其状态。它使应用程序的响应速度更快,并且用户在执行时获得了有关状态的反馈。

这个链接有更多关于如何使用它:

如果您不能使用pcntl_fork,您总是可以退回到快速返回一个触发 AJAX 请求以从队列中执行更多项目的页面。


mvds提醒以下几点(可以应用于特定的服务器配置):不要fork整个 apache webserver,而是启动一个单独的进程。让这个过程产生一个继续存在的孩子。寻找proc_open在您的 php 脚本和进程之间获得完整的 fd 交互。

于 2010-07-17T05:48:22.037 回答
5

我不希望客户看到页面完成后可能发生的漫长过程。

可悲的是,页面直到漫长的过程完成后才完成- 因此您所要求的是不可能的(以您推断的方式实施)我害怕。

这里的关键,正如 Jhong 的回答所指出的,并且由 animusen 的评论相反地建议,是我们作为 Web 开发人员对 HTTP 所做的全部重点是尽快响应请求 /end - 就是这样,所以如果你重新做任何其他事情,然后它指向一些可能会更好的设计决策:)

通常,您在返回“页面”后执行您正在执行的附加任务并将其移交给其他进程,通常这意味着将任务放入作业队列并让 cli 守护程序或 cron 作业将其拾取并执行需要。

确切的解决方案特定于您正在做的事情,以及不同(一组)问题的答案;但是对于这一点,它归结为:不,您无法关闭连接,并且建议您考虑从该脚本/页面中重构长时间运行的进程。

于 2010-07-17T06:28:04.107 回答
4

看看PHP 的ignore_user_abort-setting。您可以使用该ignore_user_abort()功能进行设置。

在以下重复问题中给出了(可选)使用示例(并且已由 OP 报告工作):

它基本上参考了 PHP 手册中的用户注释。一个中心是

这也是我建议您研究的以下两个的基础:

于 2010-07-17T09:16:00.387 回答
3

不要fork整个 apache 网络服务器,而是启动一个单独的进程。让这个过程产生一个继续存在的孩子。寻找proc_open在您的 php 脚本和进程之间获得完整的 fd 交互。

于 2010-07-17T08:52:26.330 回答
2

我们通过将需要完成的工作插入作业队列来解决这个问题,然后让 cron-script 定期提取后端作业。可能不完全是您所需要的,但它非常适用于数据密集型流程。

(您也可以使用 Zend Server 的作业队列,如果您有一大笔现金并且想要一个久经考验的解决方案)

于 2010-07-17T09:20:20.347 回答