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