【问题标题】:PHP script with sleep() does not exit on connection close带有 sleep() 的 PHP 脚本在连接关闭时不会退出
【发布时间】:2012-01-29 14:35:35
【问题描述】:

我有一个执行此操作的 PHP 脚本:

$sec = 1;
$id = 1;
while ($sec<20) {
    sleep(1);
    mysql_query("update test set sec = $sec where id = $id");
    $sec++;
}

每当我在浏览器中加载脚本时,即使我在 5 秒后关闭浏览器窗口,它也会继续运行。如何更改此设置,以便在关闭浏览器窗口时,脚本将退出?

【问题讨论】:

  • 你的脚本有什么问题?您根本没有测试浏览器关闭事件(如果它甚至可能在服务器端!),您只需测试 20 秒就可以了。你想知道什么?
  • @hakre 对不起,我不明白你的评论..
  • 您一直在问一个问题,但我发现您的代码没有任何努力显示/针对您的要求。
  • 您在问如何解决您从一开始就不应该使用的解决方案的缺点。问题在您的应用程序中根深蒂固,也许您可​​以详细说明一下?

标签: php


【解决方案1】:

你不能。将 HTTP 请求发送到服务器后,即使客户端已断开连接,PHP 脚本仍将继续执行。

在某些情况下,脚本会在打印内容时退出,但由于您没有打印任何内容,因此它不会退出。

【讨论】:

  • 我可以通过header 重定向来实现这一点吗?
  • 您可以通过header() 调用重定向,但您仍然不知道用户何时/是否断开连接。
  • 看起来有几个 php 函数旨在检查连接是否仍然存在,但在尝试了所有这些函数之后,没有一个工作..
  • 即使我在屏幕上打印一些东西,脚本也不会使用任何连接处理函数退出
  • 'something' 是任意的......服务器、代理、网络上的任何缓存都会阻止网络阻止网络服务器检测到断开连接。发送 大量 空格可能会有所帮助(请执行 flush() 这个,但出于所有实际目的,"you can't" 尽可能接近正确。
【解决方案2】:

ignore_user_abort 函数设置客户端断开连接是否应该中止脚本执行。您需要在脚本的开头添加它

ignore_user_abort(false);

【讨论】:

  • 这不起作用..把它放在顶部但是当我关闭浏览器/选项卡时脚本继续更新mysql记录。
  • 尝试在循环末尾添加一个输出,以便 php 可以更好地检测用户中止。例如,您可以回显一个空格。
【解决方案3】:

很大程度上取决于网络服务器将哪些信息传递回 PHP 解释器 - 即使作为 CLI 运行,PHP 也可能仅在客户端尝试写入其 pty 时检测到客户端已中止。

在某些情况下,网络服务器可能向解释器发送信号。但是 PHP 没有可靠的方法来检测 HTTP 连接是否真的被中止了。

但是,考虑到通过 HTTP 维护长连接所固有的复杂性,它提出了一个问题,即为什么要创建一个正常发生这种情况的场景。

【讨论】:

    【解决方案4】:

    您可以使用在关闭浏览器时销毁的会话变量,如果不再设置,您可以中断操作。

    【讨论】:

    • 试过了,没用。我在脚本开头设置了session_start(),还设置了$_SESSION['alive'] = 1,并在启动更新命令之前一直检查它是否存在。
    【解决方案5】:

    PHP 脚本在您的 Web 服务器上的进程中运行。简单地关闭浏览器并不一定会终止此过程。这意味着您的脚本可能会继续执行,即使浏览器连接已关闭。

    但可以配置为不这样做...

    看函数

    ignore_user_abort();
    

    将它放在脚本的顶部应该会在用户关闭浏览器后停止运行

    ignore_user_abort(false);
    

    【讨论】:

    • 这不起作用..把它放在顶部但是当我关闭浏览器/选项卡时脚本继续更新mysql记录。
    • 尝试一次。在您的脚本中回显某些内容。因为在尝试向客户端发送信息之前,PHP 不会检测到用户已中止连接
    • 即使在脚本中回显某些内容后,当我关闭它时它也不会停止。
    【解决方案6】:

    PHP connection_aborted() Does not always works

    TCP 要求客户端确认所有发送的数据包,因此服务器至少应将此检测为发送超时...

    session_write_close();//to make flush work
    while (connection_status() !== 0) {//this will work if the connection is properly shutdown
                                       //or if it is simply disconnected...
      sleep(1);
      echo "whatever";
      ob_flush();
      flush();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-25
      • 1970-01-01
      • 2021-08-13
      • 1970-01-01
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 2018-08-21
      相关资源
      最近更新 更多