41

我想根据一些表单输入运行一个相对耗时的脚本,但我不想求助于 cron,所以我想知道通过 ajax 请求的 php 页面是否会继续执行直到完成,或者如果用户离开页面。

直到文件末尾的 json_encode 才真正输出到浏览器,那么在此之前的所有内容仍然会执行吗?

4

5 回答 5

77

这取决于。

http://us3.php.net/manual/en/features.connection-handling.php

当 PHP 脚本正常运行时,NORMAL 状态处于活动状态。如果远程客户端断开连接,则 ABORTED 状态标志打开。远程客户端断开连接通常是由用户点击他的 STOP 按钮引起的。

您可以决定是否希望客户端断开连接导致脚本中止。有时,即使没有远程浏览器接收输出,始终让脚本运行完成也很方便。但是,默认行为是在远程客户端断开连接时中止您的脚本。可以通过 ignore_user_abortphp.ini 指令以及相应的 php_value ignore_user_abortApache httpd.conf 指令或 ignore_user_abort()函数来设置此行为。

这似乎是说您的问题的答案是“是的,如果用户离开页面,脚本将终止”。

但是要意识到,根据使用的后端 SAPI(例如mod_php),php 无法检测到客户端已中止连接,直到尝试向客户端发送信息。如果您长时间运行的脚本没有发出flush(),即使用户关闭了连接,该脚本也可能继续运行。

使事情复杂化的是,即使您确实发出定期调用flush(),打开输出缓冲也会导致这些调用陷入陷阱,并且在脚本完成之前不会将它们发送到客户端!

复杂的事情是,如果您安装了缓冲响应的 Apache 处理程序(例如mod_gzip),那么 php 将再次检测不到连接已关闭,并且脚本将继续进行卡车运输。

呸。

于 2009-08-14T21:35:42.827 回答
6

这取决于您的设置 - 通常它会停止,但您可以使用ignore_user_abort()它使其继续。

于 2009-08-14T21:28:48.380 回答
1

根据 web 服务器和/或 PHP 的配置,当用户终止 HTTP 连接时,PHP 进程可能会也可能不会杀死线程。如果在用户离开页面时 AJAX 请求处于挂起状态,则取决于浏览器在服务器配置(不保证)之上终止请求(不保证)不是你想听到的答案!

我建议在一个持续运行的PHP 守护程序可以轮询作业的平面文件或数据库中创建一个工作队列。它不会受到cron延迟的影响,但会将 CPU/内存使用率保持在可用水平。作业完成后,将结果放在平面文件/数据库中以进行 AJAX 提取。或者承诺在工作完成后给用户发送电子邮件(我的首选方法)。

希望有帮助

于 2009-08-14T21:35:25.653 回答
1

如果客户端/用户/下载器/查看器中止或断开连接,脚本将继续运行,直到客户端尝试刷新新数据。除非你使用过 ignore_user_abort(),否则脚本会死在那里。同样,如果不尝试将任何数据刷新到 httpd,PHP 将无法确定客户端是否仍然存在。

于 2009-08-15T03:32:16.557 回答
0

找到了我的情况的实际解决方案,它没有终止连接。我的 Apache/Php 服务器上的 SESSION 需要在下一个启动之前关闭。

浏览器在中止后等待 ajax 调用完成。

于 2010-06-22T20:07:36.420 回答