我想知道 - 当我编写了一段可以更新多达 10,000 行并且可能需要几秒钟才能完成的代码片段时,如果通过 ajax 请求访问文件时,post 查询被发送到 php 文件,那么浏览器已关闭,文件是否已完全执行?假设完成请求大约需要 25 秒,用户可能不会等待 25 秒,是否足以“ping”这个文件并让用户在 mysql 查询发生时浏览或关闭其浏览器窗口?
5 回答
请求有 3 个部分
- 连接到 Web 服务器的浏览器
- 服务器执行的 PHP 脚本
- 在数据库服务器中运行的查询
当您关闭浏览器时,与服务器的连接将关闭。服务器可能会也可能不会终止启动的 PHP 脚本(如果 PHP 作为 apache 模块运行,它将被终止,除非调用了 ignore_user_abort)。此外,Web 服务器可能对请求有时间限制,要么终止脚本,要么只向客户端发送连接超时消息,而不终止脚本,但不给它机会向浏览器发送任何内容。
这是棘手的部分——更新在数据库中运行,它不会被 web 服务器杀死,也不会被 PHP 杀死。
因此,您想要实现的是 ping 一个 PHP 脚本,即执行查询,但客户端不等待结果。您可能希望也可能不希望查询本身是异步的(PHP 脚本不等待查询),但您必须告诉客户端请求已完成,例如发送内容长度为 0 并刷新输出(实际上是 http 标头),并使用 ignore_user_abort 运行 PHP,以便继续执行。
即使客户端已断开连接,也可以使用ignore-user-abort继续运行脚本
ignore_user_abort(true);
set_time_limit(0);
您可以使用connection_status来跟踪连接是否已断开
if (connection_status()!=0) { //connection disconnected
通常不会,但您的脚本会传递ABORTED
状态。
有关连接处理的手册页中的更多详细信息: http ://www.php.net/manual/en/features.connection-handling.php
在 PHP 内部,连接状态被维护。有3种可能的状态:
0 - 正常
1 - 中止
2 - 超时
当 PHP 脚本正常运行时,NORMAL 状态处于活动状态。如果远程客户端断开连接,则 ABORTED 状态标志打开。远程客户端断开连接通常是由用户点击他的 STOP 按钮引起的。
关闭浏览器后,它会在收到回复之前断开与服务器的连接。我不确切知道不同服务器在这种情况下的行为如何,但我假设大多数服务器将中止他们正在处理的线程以回复请求。
此外,不同的操作可能会有所不同 - 即文件 i/o 或数据库操作。如果是原子数据库操作,我的假设是,它会以任何方式完成。