“传输编码:在PHP中分块”。

时间:2022-10-13 23:56:00

i want to add Transfer-Encoding: chunked header to the file that i'm outputing (its just generated plain text), but when i add:

我想要添加传输编码:在我输出的文件(它刚刚生成的纯文本)中对文件进行分块页眉,但是当我添加:

header("Transfer-Encoding: chunked");
flush();

the browser doesn't want to open the file.

浏览器不想打开文件。

The webpage at ... might be temporarily down or it may have moved permanently to a new web address.

的网页…可能暂时关闭,也可能永久移动到一个新的web地址。

what i need to do for it to work?

我需要为它做些什么?

4 个解决方案

#1


2  

You need to send the Content-Length with every chunk you send. Look at Wikipedia for a first impression, how a chunked encoding looks like. Its not that trivial and in many cases its oversized.

您需要发送内容长度与发送的每一个块。看看*上给人的第一印象,它是如何被分成块的。它并不是那么微不足道,在很多情况下它都是超大的。

Update: First you send the headers, because they must always send before any content (also with chunked encoding). Then you send (for every chunk) the size (in hexadecimal) followed by the content. Remember flush() after every chunk. At last you must send a zero-size chunk to make sure, that the connection get closed properly.

更新:首先要发送标题,因为它们必须总是在任何内容之前发送(同样是用chunked编码)。然后发送(每个块)大小(十六进制)后跟内容。记住每个块之后都要刷新()。最后,您必须发送一个零大小的块以确保连接正确地关闭。

Its not tested, but something like this

它没有经过测试,但是像这样。

header("Transfer-Encoding: chunked");
echo "5\r\n";
echo "Hello";
echo "\r\n\r\n";
flush();
echo "5\r\n";
echo "World";
echo "\r\n";
flush();
echo "0\r\n\r\n";
flush();

#2


2  

As previous members said you have to follow chunked transfer encoding format.
In next example i will show how you can use one user function to follow format rules:

正如前面的成员所说的,您必须遵循chunked transfer编码格式。在下一个示例中,我将展示如何使用一个用户函数来遵循格式规则:

<?php
//set headers
header('Transfer-Encoding: chunked');
header('Content-Type: text/html');

//browsers collect first 1024 bytes
//and show page only if bytes collected
//so we will use space padding.
//if you cannot understand what it means
//check script with PADDING=0
define("PADDING", 16);

//caret return and new line characters as constant
define("RN", "\r\n");

//user function what get current output buffer data
//and prefixes it with current buffer length.
//next it call flush functions
function flush_data(){
    $str=ob_get_contents();
    ob_clean();
    echo dechex(strlen($str)).RN.$str.RN;
    ob_flush();
    flush();
}

//default HTML 5 page
echo "<!doctype html><html><head><title>Transfer-Encoding: chunked</title>";
echo "<script>";

//+padding
for($i=0;$i<PADDING;$i++){
    //64 spaces (1 block)
    echo "                                                                ";
}
echo "</script></head><body><div>";

//current output buffer will shown immediately in browser
//after this function
flush_data();

//cycle wait 1 sec before next iteration
for($i=0;$i<5;$i++)
{
    //print iteration number
    echo "$i<br>";
    flush_data();
    sleep(1);
}

echo "</div></body></html>".RN;

//terminating part of encoding format
flush_data();
echo "0\r\n\r\n";
ob_flush();
?>

Notes:

注:

  1. Check if «implicit_flush» is On in your php.ini
  2. 检查您的php.ini中是否有«implicit_flush»。
  3. Know if you overflow output buffer («output_buffering» in php.ini) it will flush automatically.
  4. 知道是否溢出输出缓冲区(在php.ini中),它将自动刷新。

#3


1  

For me when I was trying something with "Transfer-Encoding: chunked" I had to use this code to make it work:

对我来说,当我尝试“转换编码”时,我必须使用这段代码来实现它:

<?php


echo "data";
header_remove("Transfer-Encoding"); 
flush();

?>

This code will still have the "Transfer-Encoding: chunked" header.

此代码仍然具有“传输编码:chunked”头。

It automatically sets the Transfer-Encoding heading when you use flush but when it set it manually it fails, so to prevent any problems try to remove it. Also make sure that you remove the heading on the line before you do your first flush to prevent errors.

当您使用刷新时,它会自动设置转换编码的标题,但是当它手动设置时,它会失败,因此,为了防止任何问题,尝试删除它。还要确保在第一次刷新之前删除该标题,以防止出现错误。

#4


-2  

Use ob_flush(); before flush();

使用ob_flush();在冲洗之前();

Sample code:

示例代码:

<?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);
        }

?>

#1


2  

You need to send the Content-Length with every chunk you send. Look at Wikipedia for a first impression, how a chunked encoding looks like. Its not that trivial and in many cases its oversized.

您需要发送内容长度与发送的每一个块。看看*上给人的第一印象,它是如何被分成块的。它并不是那么微不足道,在很多情况下它都是超大的。

Update: First you send the headers, because they must always send before any content (also with chunked encoding). Then you send (for every chunk) the size (in hexadecimal) followed by the content. Remember flush() after every chunk. At last you must send a zero-size chunk to make sure, that the connection get closed properly.

更新:首先要发送标题,因为它们必须总是在任何内容之前发送(同样是用chunked编码)。然后发送(每个块)大小(十六进制)后跟内容。记住每个块之后都要刷新()。最后,您必须发送一个零大小的块以确保连接正确地关闭。

Its not tested, but something like this

它没有经过测试,但是像这样。

header("Transfer-Encoding: chunked");
echo "5\r\n";
echo "Hello";
echo "\r\n\r\n";
flush();
echo "5\r\n";
echo "World";
echo "\r\n";
flush();
echo "0\r\n\r\n";
flush();

#2


2  

As previous members said you have to follow chunked transfer encoding format.
In next example i will show how you can use one user function to follow format rules:

正如前面的成员所说的,您必须遵循chunked transfer编码格式。在下一个示例中,我将展示如何使用一个用户函数来遵循格式规则:

<?php
//set headers
header('Transfer-Encoding: chunked');
header('Content-Type: text/html');

//browsers collect first 1024 bytes
//and show page only if bytes collected
//so we will use space padding.
//if you cannot understand what it means
//check script with PADDING=0
define("PADDING", 16);

//caret return and new line characters as constant
define("RN", "\r\n");

//user function what get current output buffer data
//and prefixes it with current buffer length.
//next it call flush functions
function flush_data(){
    $str=ob_get_contents();
    ob_clean();
    echo dechex(strlen($str)).RN.$str.RN;
    ob_flush();
    flush();
}

//default HTML 5 page
echo "<!doctype html><html><head><title>Transfer-Encoding: chunked</title>";
echo "<script>";

//+padding
for($i=0;$i<PADDING;$i++){
    //64 spaces (1 block)
    echo "                                                                ";
}
echo "</script></head><body><div>";

//current output buffer will shown immediately in browser
//after this function
flush_data();

//cycle wait 1 sec before next iteration
for($i=0;$i<5;$i++)
{
    //print iteration number
    echo "$i<br>";
    flush_data();
    sleep(1);
}

echo "</div></body></html>".RN;

//terminating part of encoding format
flush_data();
echo "0\r\n\r\n";
ob_flush();
?>

Notes:

注:

  1. Check if «implicit_flush» is On in your php.ini
  2. 检查您的php.ini中是否有«implicit_flush»。
  3. Know if you overflow output buffer («output_buffering» in php.ini) it will flush automatically.
  4. 知道是否溢出输出缓冲区(在php.ini中),它将自动刷新。

#3


1  

For me when I was trying something with "Transfer-Encoding: chunked" I had to use this code to make it work:

对我来说,当我尝试“转换编码”时,我必须使用这段代码来实现它:

<?php


echo "data";
header_remove("Transfer-Encoding"); 
flush();

?>

This code will still have the "Transfer-Encoding: chunked" header.

此代码仍然具有“传输编码:chunked”头。

It automatically sets the Transfer-Encoding heading when you use flush but when it set it manually it fails, so to prevent any problems try to remove it. Also make sure that you remove the heading on the line before you do your first flush to prevent errors.

当您使用刷新时,它会自动设置转换编码的标题,但是当它手动设置时,它会失败,因此,为了防止任何问题,尝试删除它。还要确保在第一次刷新之前删除该标题,以防止出现错误。

#4


-2  

Use ob_flush(); before flush();

使用ob_flush();在冲洗之前();

Sample code:

示例代码:

<?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);
        }

?>