【问题标题】:Can PHP scripts continue to run even if the user closed the browser?即使用户关闭了浏览器,PHP 脚本还能继续运行吗?
【发布时间】:2010-12-12 02:54:27
【问题描述】:

例如,有一个非常简单的 PHP 脚本可以更新数据库中的一些表,但是这个过程需要很长时间(可能 10 分钟)。因此,即使用户关闭浏览器,我也希望此脚本继续处理,因为有时用户不会等待,他们会关闭浏览器或转到另一个网页。

【问题讨论】:

  • 因此,如果我想将浏览器请求与作业的执行分离,我该如何请求另一个 php 脚本,而用户当前的请求仍在正常继续。因此,当用户请求任何 url 时,该请求将启动另一个脚本(独立于用户浏览器和其他请求工作)。用户将继续正常浏览网站

标签: php


【解决方案1】:

如果任务需要 10 分钟,请不要使用浏览器直接执行。您还有很多其他选择:

  • 使用 cronjob 执行任务 定期。
  • 有浏览器 请求将新行插入到 数据库表,以便定期 cronjob 可以处理新行和 执行 PHP 脚本 适当的论据
  • 拥有 浏览器请求写入消息 队列系统,它有一个订阅者 监听此类事件(然后 执行脚本)。

虽然其中一些建议对您的情况来说可能是多余的,但关键的组合功能是将浏览器请求与作业的执行分离,以便它可以异步完成。

如果您需要浏览器窗口更新进度,则需要使用定期执行的 AJAX 请求来检索作业状态。

【讨论】:

  • 因此,如果我想将浏览器请求与作业的执行分离,我该如何请求另一个 php 脚本,而用户当前的请求仍在正常继续。因此,当用户请求任何 url 时,该请求将启动另一个脚本(独立于用户浏览器和其他请求工作)。用户将继续正常在网站上冲浪我该怎么做?
  • 看到那些要点了吗?这些都是做到这一点的方法。在大多数情况下,设置一个保存后台进程输入的小型数据库表可以正常工作。然后,您可以启动一些 PHP 脚本来执行作业,通过 cron 或其他方法。
  • 您在数据库中的队列中粘贴了一条作业记录。该记录可以包含用户提供给您的任何数据。 cron 作业查看队列,获取下一个作业,读取用户提供的参数,然后使用这些输入来完成它的工作。仔细阅读大卫的第二个要点。这正是您想要做的。
  • 如何执行记录到数据库新行的 php URL(不是脚本),因为我使用框架。所以常规的 cron 作业可以处理
【解决方案2】:

要直接回答您的问题,请参阅ignore_user_abort

更广泛地说,您可能在这里遇到了架构问题。

如果许多用户都可以启动这些东西,您会希望 Web 应用程序将作业添加到某种队列中,并有一定数量的后台进程来处理所有工作。

【讨论】:

    【解决方案3】:

    客户端终止连接后PHP脚本会继续运行(不这样做会有安全风险),但最多只能到max_execution_time(在php.ini中设置或通过PHP脚本设置,一般默认30秒) )..

    例如:

    <?php
        $fh = fopen("bluh.txt", 'w');
        for($i=0; $i<20; $i++) {
            echo $i."<br/>";
            fwrite($fh,$i."\n");
            sleep(1);
        }
        fclose($fh);
    ?>
    

    开始在您的浏览器中运行它并在完成之前关闭浏览器。您会发现 20 秒后该文件包含了 $i 的所有值。

    将 for 循环的上限更改为 100 而不是 20,您会发现它只在 0 到 29 之间运行。由于 PHP 的 max_execution_time,脚本超时并终止。

    【讨论】:

    • 不错的答案。但是,如果脚本尝试将输出刷新到浏览器,而不是写入文件,例如使用echo "..."; flush(); ob_flush();,该怎么办?我认为脚本将终止,因为输出流将不再可用。
    • @ban-geoengineering 我一开始以为你是对的,但我测试了你的建议(上面的代码已经每秒都使用'echo')但是在我的系统上,当标签关闭时脚本没有中止。奇怪。
    【解决方案4】:

    如果脚本完全基于服务器(不向用户反馈),即使客户端关闭,也会这样做。

    PHP 的一般架构是客户端向脚本发送请求,该脚本向用户提供回复。如果没有任何内容返回给用户,即使用户不再在另一端,脚本仍将执行。更简单:它们不是常规脚本上服务器和客户端之间的恒定连接。

    【讨论】:

      【解决方案5】:

      您可以使用包含时间和要运行的命令的 crontab 文件让 PHP 脚本每 20 分钟运行一次。在这种情况下,它将是 php 脚本。

      【讨论】:

        【解决方案6】:

        是的。服务器不知道用户是否关闭了浏览器。至少它不会立即注意到这一点。

        否:服务器可能(取决于它的配置方式)不允许 php 脚本运行 10 分钟。在便宜的共享主机上,我不会依赖运行超过合理响应时间的脚本。

        【讨论】:

          【解决方案7】:

          无论客户端在做什么,服务器端脚本都会继续执行它正在执行的操作。

          编辑:顺便问一下,您确定要打开需要 10 分钟的页面吗?我建议您使用任务队列(其项目由 cron 及时执行)并将用户重定向到“好的,我在它”页面。

          【讨论】:

          • ... 不完全正确:通常,有一些守卫可以“杀死”长时间运行的 php 脚本:这些脚本采用 crontab 条目的形式。
          • @jldupont:我不是php人,但是这些脚本和客户端有关系吗?
          • @shanyu - 不知道 jldupont 在说什么。 php 的配置变量可以杀死长时间运行的脚本,但它们与 cron 完全无关。
          • 这不是真的,无论客户端如何,服务器端脚本并不总是继续运行......
          猜你喜欢
          • 2016-05-08
          • 1970-01-01
          • 2016-05-20
          • 1970-01-01
          • 2011-08-25
          • 2015-04-09
          • 1970-01-01
          • 1970-01-01
          • 2015-01-28
          相关资源
          最近更新 更多