Close connection in PHP but keep executing script

醉酒当歌 提交于 2019-12-19 09:09:16

问题


Anyone know how to close the connection (besides just flush()?), but keep executing some code afterwards.

I don't want the client to see the long process that may occur after the page is done.


回答1:


You might want to look at pcntl_fork() -- it allows you to fork your current script and run it in a separate thread.

I used it in a project where a user uploaded a file and then the script performed various operations on it, including communicating with a third-party server, which could take a long time. After the initial upload, the script forked and displayed the next page to the user, and the parent killed itself off. The child then continued executing, and was queried by the returned page for its status using AJAX. it made the application much more responsive, and the user got feedback as to the status while it was executing.

This link has more on how to use it:

  • Thorough look at PHP's pcntl_fork() (Apr 2007; by Frans-Jan van Steenbeek)

If you can't use pcntl_fork, you can always fall back to returning a page quickly that fires an AJAX request to execute more items from a queue.


mvds reminds the following (which can apply in a specific server configuration): Don't fork the entire apache webserver, but start a separate process instead. Let that process fork off a child which lives on. Look for proc_open to get full fd interaction between your php script and the process.




回答2:


I don't want the client to see the long process that may occur after the page is done.

sadly, the page isn't done until after the long process has finished - hence what you ask for is impossible (to implement in the way you infer) I'm afraid.

The key here, pointed to by Jhong's answer and inversely suggested by animusen's comment, is that the whole point of what we do with HTTP as web developers is to respond to a request as quickly as possible /end - that's it, so if you're doing anything else, then it points to some design decision that could perhaps have been a little better :)

Typically, you take the additional task you are doing after returning the 'page' and hand it over to some other process, normally that means placing the task in a job queue and having a cli daemon or a cron job pick it up and do what's needed.

The exact solution is specific to what you're doing, and the answer to a different (set of) questions; but for this one it comes down to: no you can't close the connection, and one would advise you look at refactoring the long running process out of that script / page.




回答3:


Take a look at PHP's ignore_user_abort-setting. You can set it using the ignore_user_abort() function.

An example of (optional) use has been given (and has been reported working by the OP) in the following duplicate question:

  • close a connection early (Sep 2008)

It basically gives reference to user-notes in the PHP manual. A central one is

  • Connection Handling user-note #71172 (Nov 2006)

which is also the base for the following two I'd like to suggest you to look into:

  • Connection Handling user-note #89177 (Feb 2009)
  • Connection Handling user-note #93441 (Sep 2009)



回答4:


Don't fork the entire apache webserver, but start a separate process instead. Let that process fork off a child which lives on. Look for proc_open to get full fd interaction between your php script and the process.




回答5:


We solved this issue by inserting the work that needs to be done into a job queue, and then have a cron-script pick up the backend jobs regularly. Probably not exactly what you need, but it works very well for data-intensive processes.

(you could also use Zend Server's job queue, if you've got a wad of cash and want a tried-and-tested solution)



来源:https://stackoverflow.com/questions/3270414/close-connection-in-php-but-keep-executing-script

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!