Php 关闭连接后继续处理

Php 关闭连接后继续处理,php,Php,在PHP中是否有一种方法可以关闭连接(本质上是告诉浏览器没有更多的数据)但继续处理。我考虑的具体情况是,我希望提供缓存数据,然后如果缓存已过期,我仍会提供缓存数据以获得快速响应,关闭连接,但继续处理以重新生成和缓存新数据。本质上,唯一的目的是让网站看起来更具响应性,因为当用户等待内容重新生成时,不会出现偶尔的延迟 更新: 加上有最接近的答案,我一直在寻找。为了向一些人澄清,我正在寻找能够实现以下步骤的东西: 用户请求页面 连接打开到服务器 PHP检查缓存是否已过期,如果仍然是新的,则提供缓存并关

在PHP中是否有一种方法可以关闭连接(本质上是告诉浏览器没有更多的数据)但继续处理。我考虑的具体情况是,我希望提供缓存数据,然后如果缓存已过期,我仍会提供缓存数据以获得快速响应,关闭连接,但继续处理以重新生成和缓存新数据。本质上,唯一的目的是让网站看起来更具响应性,因为当用户等待内容重新生成时,不会出现偶尔的延迟

更新:

加上有最接近的答案,我一直在寻找。为了向一些人澄清,我正在寻找能够实现以下步骤的东西:

  • 用户请求页面
  • 连接打开到服务器
  • PHP检查缓存是否已过期,如果仍然是新的,则提供缓存并关闭连接(在此处结束)。如果过期,请继续执行4
  • 服务过期缓存
  • 关闭连接,以便浏览器知道它没有等待更多数据
  • PHP重新生成新数据并将其缓存
  • PHP关闭
  • 更新:


    这很重要,它必须是一个纯粹的PHP解决方案。安装其他软件不是一个选项。

    PHP没有这种持久性(默认情况下)。我能想到的唯一方法是运行CRON Job来预先填充缓存。

    < P>如果您这样做是为了缓存内容,您可能需要考虑使用现有的缓存解决方案,例如.< /p> ,可以通过设置时间限制为无限,忽略连接

    来实现。
    <?php
    ignore_user_abort(true);
    set_time_limit(0);
    

    否。就Web服务器而言,来自浏览器的请求由PHP引擎处理,仅此而已。请求的持续时间与PHP相同

    您可能能够
    fork()

    可以从PHP-CLI编译和运行程序(不在共享主机>VPS上) 缓存 因为缓存,我不会那样做。我会使用redis作为我的浏览器。尤其是当您使用编译它时

    脱机处理 安装消息队列时,还可以执行延迟放置。但是我会使用redis/来完成另一个消息队列部分,因为redis会更快,特别是如果您使用PHP客户机库(在C用户空间中)

    无法从PHP-CLI编译或运行程序(在共享主机上) 设置时间限制 大多数情况下,在共享主机上至少设置0是不可用的(因为安全模式或
    max\u execution\u time
    指令)。此外,共享主机提供商不希望用户长时间占用PHP进程。大多数情况下,默认限制设置为30

    克朗 使用cron将数据写入光盘。一些stackoverflow主题已经解释了这一点:

    也很简单,但还是很粗糙。我认为你应该升级(>VPS)当你必须这样做黑客

    异步请求
    最后,您可以使用Cache_lite缓存数据请注意共享主机不喜欢占用大量长时间运行的PHP进程。我只使用一个后台进程,当它达到
    max execution time
    指令时调用另一个后台进程。我会记录脚本启动的时间和两个缓存调用之间的时间,我会测量所花费的时间,以及当它接近我执行另一个异步请求的时间。我将使用来确保只有一个进程正在运行。这样我就不会尿的供应商,它可以做到。另一方面,我不认为我会写这篇文章,因为如果你问我的话,这篇文章有点粗糙。当我达到这个规模时,我会升级到VPS。

    我终于找到了一个解决方案(多亏了谷歌,我不得不不断尝试不同的搜索词组合)。多亏了arr1上的评论(这大约是整个页面的三分之二)


    如果在fastcgi下运行,您可以使用非常漂亮的:

    fastcgi_完成_请求()


    更详细的信息是可用的。

    据我所知,除非您正在运行FastCGI,否则您无法断开连接并继续执行(除非您得到了内切黑格的工作答案,我失败了)。因此,您可以:

  • 使用cron或类似的工具来安排此类任务
  • 使用子进程完成作业
  • 但情况变得更糟了。即使您使用
    proc\u open()
    生成子进程,PHP也会在关闭连接之前等待它完成,即使在调用
    exit()
    die()
    一些未定义的函数导致致命错误()。我发现的唯一解决方法是生成一个子进程,该子进程本身会生成一个子进程,如下所示:

    function doInBackground ($_variables, $_code)
    {
        proc_open (
            'php -r ' .     
                escapeshellarg ("if (pcntl_fork() === 0) { extract (unserialize (\$argv [1])); $_code }") .
                ' ' . escapeshellarg (serialize ($_variables)),
            array(), $pipes 
        );
    }
    
    $message = 'Hello world!';
    $filename = tempnam (sys_get_temp_dir(), 'php_test_workaround');
    $delay = 10;
    
    doInBackground (compact ('message', 'filename', 'delay'), <<< 'THE_NOWDOC_STRING'
        // Your actual code goes here:
        sleep ($delay);
        file_put_contents ($filename, $message);
    THE_NOWDOC_STRING
    );
    
    函数doInBackground($\u变量,$\u代码)
    {
    程序打开(
    “php-r”。
    escapeshellarg(“if(pcntl_fork()==0){extract(unserialize(\$argv[1]);$_code}”)。
    ''.escapeshellarg(序列化($_变量)),
    数组(),$pipes
    );
    }
    $message='helloworld!';
    $filename=tempnam(sys_get_temp_dir(),'php_test_workaround');
    $delay=10;
    
    doInBackground(compact('message','filename','delay'),关闭连接意味着HTTP或MySQL?@powtac HTTP。我始终可以重新打开MySQL连接。我希望脚本继续运行(短时间和有限时间)在HTTP连接关闭后。大多数情况下,至少在共享主机上,此设置时间限制不可用于设置0。另一方面,共享主机提供商不希望用户长时间占用PHP进程。你是对的,但我认为这是实现内噬所需+1的唯一方法,但也是值得的更值得一提的是,PHP通常会忽略用户中止。@Alfred我不在共享主机上,但仍有一些限制。我知道我可以设置时间限制(0),并且缓存相当快,生成和缓存大约需要半秒,我只是试图避免在用户获得
    function doInBackground ($_variables, $_code)
    {
        proc_open (
            'php -r ' .     
                escapeshellarg ("if (pcntl_fork() === 0) { extract (unserialize (\$argv [1])); $_code }") .
                ' ' . escapeshellarg (serialize ($_variables)),
            array(), $pipes 
        );
    }
    
    $message = 'Hello world!';
    $filename = tempnam (sys_get_temp_dir(), 'php_test_workaround');
    $delay = 10;
    
    doInBackground (compact ('message', 'filename', 'delay'), <<< 'THE_NOWDOC_STRING'
        // Your actual code goes here:
        sleep ($delay);
        file_put_contents ($filename, $message);
    THE_NOWDOC_STRING
    );