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