如何通过AJAX发出长PHP请求,定期检查状态更新,并在请求取消时关闭脚本


How should I make a long PHP request via AJAX, periodically check for status updates, and close the script if the request cancels?

我正在开发的PHP web应用程序的一部分需要做以下工作:

  1. 向PHP脚本发出AJAX请求,这可能需要1秒到1小时,并在完成后在页面上显示输出。
  2. 定期更新网页上的加载条,由长期运行的PHP脚本中的状态变量定义。
  3. 允许长时间运行的PHP脚本检测AJAX请求是否被取消,以便它可以及时关闭。

我当前的解决方案:

  • client.php:创建一个AJAX请求到request.php,然后每秒一个请求到status.php,直到初始请求完成。在多个应用实例同时运行的情况下,生成并传递一个唯一标识符(uid)。
  • request.php:每次取得进度时,将当前进度百分比保存到$_SESSION["progressBar"][uid]。(每次都必须运行session_start()和session_write_close()。)完成后,返回client.php需要的数据。
  • status.php:运行session_start(),返回$_SESSION["progressBar"][uid],并运行session_write_close()

不足之处:

我的解决方案满足我的前两个要求。第三,我想在request.php中使用connection_aborted()来知道请求是否被取消。但是,医生说:

PHP在尝试向客户端发送信息之前不会检测到用户已经终止连接。简单地使用echo语句并不能保证信息被发送,参见flush()。

我可以简单地给出无意义的输出,但是PHP 必须在每次调用session_start()时发送一个cookie。我想使用相同的会话,但是文档说:

当使用会话cookie时,为session_id()指定一个id将总是在session_start()被调用时发送一个新的cookie,无论当前会话id是否与被设置的相同。

我的解决方案,没有一个是我满意的:

    一个状态数据库,或写入临时文件,或一个任务管理系统。这似乎比我需要的更复杂!
  • 自定义会话处理程序。这与上面的解决方案基本相同。
  • 在一个请求中同时传输进度数据和结果数据。这解决了所有问题,但实际上我需要重新实现AJAX。这不可能是对的。

请告诉我我错过了什么!为什么PHP不能立即知道连接何时终止?为什么PHP必须重新发送cookie,即使它是完全相同的?这些问题的答案都将大有帮助!

我衷心的感谢。

为什么不设置第二个会话变量,由唯一的请求标识符和访问时间戳组成,从status.php

如果客户端关闭,它停止从status.php获取更新,并且会话变量停止更新,如果变量在一定时间内没有更新,则触发request.php的干净关闭。