【问题标题】:“Transfer-Encoding: chunked” header in PHP. What is "padding" for?PHP 中的“Transfer-Encoding: chunked”标头。什么是“填充”?
【发布时间】:2012-11-26 13:35:17
【问题描述】:

正如对上一个问题 (PHP External Oauth : how to displaying a waiting message while waiting for callback (not using AJAX)) 的回复中所建议的,我正在使用传输编码:分块以在执行某些任务时显示等待消息。我的第一次尝试失败了,我在这个问题“Transfer-Encoding: chunked” header in PHP 中找到了解决方案。有 1024 个空格的“填充”。没有这个填充它不起作用。我已经用谷歌搜索了,但我找不到这个填充的用途。这是示例代码(来自相关问题)。

<?php
        header('Content-Encoding', 'chunked');
        header('Transfer-Encoding', 'chunked');
        header('Content-Type', 'text/html');
        header('Connection', 'keep-alive');

        ob_flush();
        flush();

        $p = "";  //padding
        for ($i=0; $i < 1024; $i++) { 
            $p .= " ";
        };
        echo $p;

        ob_flush();
        flush();

        for ($i = 0; $i < 10000; $i++) {
            echo "string";
            ob_flush();
            flush();
            sleep(2);
        }

?>

有没有人解释一下为什么它可以在没有“填充”的情况下工作和不工作?

【问题讨论】:

  • 没有填充会发生什么?
  • 对不起,我出去了一段时间。没有填充,页面保持空白,直到脚本完成,然后提供所有内容(我没有尝试 10.000 次迭代,但只有 10 次 :))

标签: php padding transfer-encoding


【解决方案1】:

据我所知,填充用于填充 server 缓冲区。

如果没有它,服务器将等待 PHP 填充它,然后刷新它 - 即使在 PHP 代码中您执行 flush()

相关:

【讨论】:

  • 感谢您的链接。看来这确实和apache环境关系更大。
【解决方案2】:

我不知道这个填充应该做什么,实际上它不应该工作(如果我错了,有人可能会启发我)。分块编码的想法是您以块的形式发送数据。每个块由包含块长度的行组成,后跟换行符,然后是块的数据。响应可以包含任意数量的块。所以基本上包含“Hello”的 3 个块的响应如下所示:

5 <--- this is the length of the chunk, that is "Hello" == 5 chars
Hello  <--- This is a the actual data
<-- an empty line is between the chunks
5
Hello

5
Hello

<-- send two empty lines to end the transmission

所以我会把它改写成这样的:

<?php
        header('Content-Encoding', 'chunked');
        header('Transfer-Encoding', 'chunked');
        header('Content-Type', 'text/html');
        header('Connection', 'keep-alive');

        ob_flush();
        flush();

        for ($i = 0; $i < 10000; $i++) {
            $string = "string";
            echo strlen($string)."\r\n"; // this is the length
            echo $string."\r\n"; // this is the date
            echo "\r\n"; // newline between chunks
            ob_flush(); // rinse and repeat
            flush();
            sleep(2);
        } 
        echo  "\r\n"; // send final empty line
        ob_flush();
        flush();

?>

上面的代码在所有情况下都不起作用(例如,包含换行符或非 ascii 编码的字符串),因此您必须根据您的用例对其进行调整。

【讨论】:

  • 这个脚本给了我以下输出:“6 串 6 串 6 串 6 串 6 串 6 串 6 串 6 串 6 串 6 串”(仅 10 次迭代),但传输没有分块.我错过了什么?在 Apache / nginx 上设置什么特别的(用作反向代理,指令 proxy_buffering off;
猜你喜欢
  • 2018-09-12
  • 2011-11-09
  • 2017-10-03
  • 2021-08-18
  • 1970-01-01
  • 1970-01-01
  • 2020-04-17
相关资源
最近更新 更多