PHP 中的“传输编码:分块”标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4809774/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"Transfer-Encoding: chunked" header in PHP
提问by Ddwerffdsf
i want to add Transfer-Encoding: chunked
header to the file that i'm outputing (its just generated plain text), but when i add:
我想将Transfer-Encoding: chunked
标题添加到我正在输出的文件中(它只是生成的纯文本),但是当我添加时:
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.
位于 ... 的网页可能暂时关闭,或者可能已永久移至新网址。
what i need to do for it to work?
我需要做什么才能让它工作?
回答by KingCrunch
You need to send the Content-Length
with every chunk you send. Look at Wikipediafor a first impression, how a chunked encoding looks like. Its not that trivial and in many cases its oversized.
您需要Content-Length
随发送的每个块一起发送。看看维基百科的第一印象,分块编码的样子。它不是那么微不足道,而且在许多情况下它的尺寸过大。
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.
更新:首先发送标头,因为它们必须始终在任何内容之前发送(也使用分块编码)。然后您发送(对于每个块)大小(十六进制),然后是内容。flush()
在每个块之后记住。最后,您必须发送一个零大小的块以确保连接正确关闭。
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();
回答by pashak
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:
正如以前的成员所说,您必须遵循分块传输编码格式。
在下一个示例中,我将展示如何使用一个用户函数来遵循格式规则:
<?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:
注意事项:
- Check if ?implicit_flush? is Onin your php.ini
- Know if you overflow output buffer (?output_buffering? in php.ini) it will flush automatically.
- 检查是否 ?implicit_flush? 是在你的php.ini
- 知道是否溢出输出缓冲区(在php.ini 中?output_buffering?)它会自动刷新。
回答by SBoys3.com
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.
此代码仍将具有“传输编码:分块”标头。
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.
当您使用刷新时,它会自动设置传输编码标题,但手动设置时它会失败,因此为防止出现任何问题,请尝试将其删除。还要确保在第一次冲洗之前删除线上的标题以防止错误。
回答by Partha Pal
Use ob_flush();
before flush();
使用ob_flush();
前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);
}
?>