我正在开发的PHP web应用程序的一部分需要做以下工作:
- 向PHP脚本发出AJAX请求,这可能需要1秒到1小时,并在完成后在页面上显示输出。
- 定期更新网页上的加载条,由长期运行的PHP脚本中的状态变量定义。
- 允许长时间运行的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
的干净关闭。