10

问题在于,无论客户端浏览器当前是否连接,PHP 脚本都会在很长一段时间内继续执行。如果客户端终止了对脚本的 Ajax 调用,那么脚本是否也会在服务器上终止?

4

4 回答 4

9

正如@metadings 所指出的,php 确实有一个名为connection_aborted() 的函数来检查连接中止。如果连接终止,它将返回 1,否则返回 0。

在较长的服务器端进程中,用户可能需要知道客户端是否与服务器断开连接,或者他是否关闭了浏览器,然后服务器可以安全地关闭该进程。

尤其是在应用程序使用 php 会话的情况下,如果我们在客户端断开连接后让长进程继续运行,那么服务器将对此会话无响应。来自同一客户端的任何其他请求都将等到前面的进程完全执行。出现这种情况的原因是进程运行时会话文件被锁定。但是,您可以有意地调用 session_write_close() 方法来解锁它。但这并非在所有情况下都可行,可能需要在进程结束时向会话写入一些内容。

现在,如果我们只在循环中调用 connection_aborted() ,那么无论连接是否关闭,它都将始终返回 0。

0 表示连接没有中止。这是误导。但是,经过重新搜索和实验,如果发现是php中的输出缓冲区是这个原因。

首先,为了检查中止,循环中的开发人员必须通过回显一些文本向客户端发送一些输出。例如:

print " ";

由于进程仍在运行,因此不会将输出发送到客户端。现在要发送输出,我们需要刷新输出缓冲区。

flush ();
ob_flush ();

然后,如果我们检查中止,那么它将给出正确的结果。

if (connection_aborted () != 0) {
  die();
}

以下是工作示例,即使您使用的是 PHP 会话,它也可以工作:

session_start ();
ignore_user_abort ( TRUE );

file_put_contents ( "con-status.txt", "Process started..\n\n" );

for($i = 1; $i <= 15; $i ++) {

    print " ";

    file_put_contents ( "con-status.txt", "Running process unit $i \n", FILE_APPEND );
    sleep ( 1 );

    // Send output to client
    flush ();
    ob_flush ();

    // Check for connection abort
    if (connection_aborted () != 0) {
        file_put_contents ( "con-status.txt", "\nUser terminated the process", FILE_APPEND );
        die ();
    }

}

file_put_contents ( "con-status.txt", "\nAll units completed.",  FILE_APPEND );

编辑 2017 年 4 月 7 日

如果有人在 Windows 上使用 Fast-Cgi,那么当连接中止时,他实际上可以使用以下代码从内存中终止 CGI 线程:

if (connection_aborted () != 0) { apache_child_terminate(); exit; }

于 2013-05-16T16:36:32.567 回答
4

查看 PHPconnection_aborted()函数。在进行处理时,您有时可以检查中止的连接以优雅地取消进度,就像在交互式线程模型中所做的那样。

于 2013-05-13T14:48:00.477 回答
1

我发现处理此超时问题的最简单方法之一是:

1:在服务器上设置一个值作为“处理”。启动一个独立的线程来做处理。
2:初始 ajax 调用返回成功
3:页面上的 javascript 进入“等待模式”,每 10 或 30 或 60 秒或 5 或 10 分钟或其他任何时间(取决于您的情况)发送一个新的 ajax 请求以查找输出服务器上的值是否仍设置为“处理”。
4:独立线程完成。它将服务器上的值设置为“完成”。
5:页面上的 javascript 进行下一个等待模式查询,并返回“完成”和相应的数据。

4b:如果长时间没有“完成”,则记录为失败。多少时间是淫秽的取决于你的情况。发送一个 ajax 调用,将值从“处理”更新为“取消”。5b:独立线程定期检查状态以确保它仍设置为“处理”。如果它看到模式转换为“取消”,它会自行取消。

于 2013-05-13T14:29:21.853 回答
1

这就是您要查找的内容:http: //php.net/manual/en/function.ignore-user-abort.php

在执行过程中停止脚本可能会导致意外结果,因此请注意购买者

于 2013-05-13T14:40:32.817 回答