【发布时间】:2010-11-19 19:11:32
【问题描述】:
我想根据一些表单输入运行一个相对耗时的脚本,但我不想求助于 cron,所以我想知道通过 ajax 请求的 php 页面是否会继续执行直到完成,或者它是否会如果用户离开页面,则停止。
直到文件末尾的 json_encode 才真正输出到浏览器,那么在此之前的所有内容仍会执行吗?
【问题讨论】:
我想根据一些表单输入运行一个相对耗时的脚本,但我不想求助于 cron,所以我想知道通过 ajax 请求的 php 页面是否会继续执行直到完成,或者它是否会如果用户离开页面,则停止。
直到文件末尾的 json_encode 才真正输出到浏览器,那么在此之前的所有内容仍会执行吗?
【问题讨论】:
这取决于您的设置 - 通常它会停止,但您可以使用 ignore_user_abort() 使其继续。
【讨论】:
ignore_user_abort() 不能保证工作,这可能在许多情况下发生。看我的回答。
根据 web 服务器和/或 PHP 的配置,PHP 进程可能会也可能不会在用户终止 HTTP 连接时终止线程。如果 AJAX 请求在用户离开页面时处于挂起状态,则取决于浏览器是否会终止服务器配置的请求(不保证)ontop(不保证)。不是你想听到的答案!
我建议在平面文件或数据库中创建一个工作队列,持续运行的PHP daemon 可以轮询作业。它不会受到cron 延迟的影响,而是将 CPU/内存使用率保持在可用水平。作业完成后,将结果放在平面文件/数据库中以进行 AJAX 提取。或者承诺在工作完成后给用户发送电子邮件(我的首选方法)。
希望有帮助
【讨论】:
视情况而定。
来自http://us3.php.net/manual/en/features.connection-handling.php:
当 PHP 脚本正常运行时 NORMAL 状态,处于活动状态。如果 远程客户端断开 ABORTED 状态标志打开。一个遥控器 客户端断开连接通常是由 用户点击了他的 STOP 按钮。
您可以决定是否要 客户端断开连接导致您的 要中止的脚本。有时它是 方便始终让您的脚本运行 即使没有完成 远程浏览器接收输出。 然而,默认行为是 当你的脚本被中止时 远程客户端断开连接。这 行为可以通过设置
ignore_user_abortphp.ini 指令为 以及通过相应的php_value ignore_user_abort阿帕奇 httpd.conf 指令或与ignore_user_abort()函数。
您的问题的答案似乎是“是的,如果用户离开页面,脚本将终止”。
但是要意识到,这取决于所使用的后端 SAPI(例如,mod_php)、php cannot detect that the client has aborted the connection until an attempt is made to send information to the client。如果您长时间运行的脚本没有发出flush(),即使用户关闭了连接,该脚本也可能继续运行。
复杂的事情是即使你确实定期调用flush(),开启output buffering会导致这些调用陷入陷阱并且在脚本完成之前不会将它们发送到客户端无论如何!
进一步使事情变得复杂的是,如果您安装了缓冲响应的 Apache 处理程序(例如 mod_gzip),那么 php 将再次检测不到连接已关闭,并且脚本将继续运输.
呼。
【讨论】:
如果客户端/用户/下载器/查看器中止或断开连接,脚本将继续运行,直到客户端尝试刷新新数据。除非你用过
ignore_user_abort(),脚本会死在那里。
同样的顺序,如果不尝试将任何数据刷新到 httpd,PHP 无法确定客户端是否仍然存在。
【讨论】:
找到了我的情况的实际解决方案,它没有终止连接。我的 Apache/Php 服务器上的 SESSION 需要在下一个启动之前关闭。
【讨论】: