如果HTTP请求被取消/关闭,PHP会自动终止脚本

时间:2013-05-13 14:12:54

标签: php ajax

问题在于,对于漫长的过程,无论客户端浏览器当前是否连接,PHP脚本都会继续执行。是否有可能如果客户端终止了对脚本的Ajax调用,那么脚本也会终止在服务器上?

4 个答案:

答案 0 :(得分:8)

正如@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 );

编辑07-APR-2017

  

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

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

答案 1 :(得分:4)

查看PHP connection_aborted()函数。在进行处理时,您有时可以检查中止连接以正常取消进度,就像在交互式线程模型中那样。

答案 2 :(得分:1)

我发现哪种方法是处理此超时问题的最简单方法是这样的:

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

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

答案 3 :(得分:1)

这就是你要找的东西: http://php.net/manual/en/function.ignore-user-abort.php

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