任何人都知道如何关闭连接(除了flush()
?),但之后继续执行一些代码。
我不希望客户看到页面完成后可能发生的漫长过程。
您可能想查看pcntl_fork()
- 它允许您分叉当前脚本并在单独的线程中运行它。
我在一个项目中使用它,用户上传文件,然后脚本对其执行各种操作,包括与第三方服务器通信,这可能需要很长时间。初始上传后,脚本分叉并向用户显示下一页,然后父进程自行关闭。然后子进程继续执行,并由返回的页面使用 AJAX 查询其状态。它使应用程序的响应速度更快,并且用户在执行时获得了有关状态的反馈。
这个链接有更多关于如何使用它:
如果您不能使用pcntl_fork
,您总是可以退回到快速返回一个触发 AJAX 请求以从队列中执行更多项目的页面。
mvds提醒以下几点(可以应用于特定的服务器配置):不要
fork
整个 apache webserver,而是启动一个单独的进程。让这个过程产生一个继续存在的孩子。寻找proc_open
在您的 php 脚本和进程之间获得完整的 fd 交互。
我不希望客户看到页面完成后可能发生的漫长过程。
可悲的是,页面直到漫长的过程完成后才完成- 因此您所要求的是不可能的(以您推断的方式实施)我害怕。
这里的关键,正如 Jhong 的回答所指出的,并且由 animusen 的评论相反地建议,是我们作为 Web 开发人员对 HTTP 所做的全部重点是尽快响应请求 /end - 就是这样,所以如果你重新做任何其他事情,然后它指向一些可能会更好的设计决策:)
通常,您在返回“页面”后执行您正在执行的附加任务并将其移交给其他进程,通常这意味着将任务放入作业队列并让 cli 守护程序或 cron 作业将其拾取并执行需要。
确切的解决方案特定于您正在做的事情,以及不同(一组)问题的答案;但是对于这一点,它归结为:不,您无法关闭连接,并且建议您考虑从该脚本/页面中重构长时间运行的进程。
看看PHP 的ignore_user_abort
-setting。您可以使用该ignore_user_abort()
功能进行设置。
在以下重复问题中给出了(可选)使用示例(并且已由 OP 报告工作):
它基本上参考了 PHP 手册中的用户注释。一个中心是
这也是我建议您研究的以下两个的基础:
不要fork
整个 apache 网络服务器,而是启动一个单独的进程。让这个过程产生一个继续存在的孩子。寻找proc_open
在您的 php 脚本和进程之间获得完整的 fd 交互。
我们通过将需要完成的工作插入作业队列来解决这个问题,然后让 cron-script 定期提取后端作业。可能不完全是您所需要的,但它非常适用于数据密集型流程。
(您也可以使用 Zend Server 的作业队列,如果您有一大笔现金并且想要一个久经考验的解决方案)