2

运行 PHP 时,您希望它立即将 HTML 返回到浏览器,关闭连接(ish),然后继续处理......

以下内容在连接为 HTTP/1.1 时有效,但在使用Apache 2.4.25, with mod_http2enabled 且您拥有支持 HTTP/2 的浏览器(例如 Firefox 52 或 Chrome 57)时无效。

发生的情况Connection: close是未发送标头。

<?php

    function http_connection_close($output_html = '') {

        apache_setenv('no-gzip', 1); // Disable mod_gzip or mod_deflate

        ignore_user_abort(true);

        // Close session (if open)

        while (ob_get_level() > 0) {
            $output_html = ob_get_clean() . $output_html;
        }

        $output_html = str_pad($output_html, 1023); // Prompt server to send packet.
        $output_html .= "\n"; // For when the client is using fgets()

        header('Connection: close');
        header('Content-Length: ' . strlen($output_html));

        echo $output_html;

        flush();

    }

    http_connection_close('<html>...</html>');

    // Do stuff...

?>

有关此问题的类似方法,请参阅:

  1. 尽早关闭连接
  2. 关闭连接后继续处理
  3. 连接关闭后继续 php 脚本

至于为什么要connection删除标头,该nghttp2库的文档(由 Apache 使用)指出:

https://github.com/nghttp2/nghttp2/blob/master/doc/programmers-guide.rst

HTTP/2 prohibits connection-specific header fields. The 
following header fields must not appear: "Connection"...

所以如果我们不能通过这个头告诉浏览器关闭连接,我们如何让它工作呢?

或者是否有另一种方式告诉浏览器它拥有 HTML 响应的所有内容,并且它不应该一直等待更多数据到达。

4

2 回答 2

2

如何向用户返回 HTTP 响应并恢复 PHP 处理

只有当 Web 服务器通过FastCGI协议与 PHP 通信时,此答案才有效。

要向用户(Web 服务器)发送回复并在后台恢复处理,而不涉及操作系统调用,请调用该fastcgi_finish_request()函数。

例子:

<?php

echo '<h1>This is a heading</h1>'; // Output sent 

fastcgi_finish_request(); // "Hang up" with web-server, the user receives what was echoed

while(true)
{
    // Do a long task here
    // while(true) is used to indicate this might be a long-running piece of code
}

需要注意什么

  • 即使用户确实收到了输出,php-fpm子进程也会很忙并且无法接受新请求,直到他们完成处理这个长时间运行的任务。

如果所有可用php-fpm的子进程都忙,那么您的用户将遇到挂页。谨慎使用。

nginx并且apache服务器都知道如何处理FastCGI协议,因此不需要将apache服务器换成nginx.

于 2017-03-24T15:49:11.077 回答
1

您可以使用特殊的子域通过 HTTP/1.1 提供您的慢速 PHP 脚本。

您需要做的就是使用 Apache 的协议指令设置第二个以 HTTP/1.1 响应的 VirtualHost:https ://httpd.apache.org/docs/2.4/en/mod/core.html#protocols

这种技术的一大优势是,您的慢速脚本可以在其他所有内容都通过 HTTP/2 流发送之后很久才将一些数据发送到浏览器。

于 2017-05-26T21:11:49.123 回答