9

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.

what i need to do for it to work?

Ddwerffdsf
  • 141
  • 1
  • 2
  • 6
  • are you also sending a `Content-Length` header? – drudge Jan 26 '11 at 20:42
  • 3
    No, you should not include the `Content-Length` header. The entire point of `Transfer-Encoding: chunked` is that your content is being dynamically generated so you don't know the content length a priori and thus cannot set this header. – james.garriss Nov 04 '11 at 12:50

4 Answers4

5

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.

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();
KingCrunch
  • 128,817
  • 21
  • 151
  • 173
  • There is really no need to think about it, unless you must send content of some MB. However, I will update my answer with basic instructions – KingCrunch Jan 26 '11 at 21:09
  • and how to convert the text into chunks? for example if my output is `Hello_World_:)` – Ddwerffdsf Jan 26 '11 at 21:17
  • That question does not make much sense... A chunk is a piece of content, that you define as a piece of content. The idea is, that you have a long running script, that will produce much data. From time to time you can send some of this data to the client to save memory and give the client something to do while waiting ;) In your case (`Hello_World_:)`) you can split this string into chunks, of course, but that really makes no sense. – KingCrunch Jan 26 '11 at 21:44
  • 3
    I'm not an expert, but I think this answer may be wrong. None of it fits with the answer here: http://stackoverflow.com/questions/2481858/how-to-make-php-generate-chunked-response . Unless I'm misunderstanding, PHP & apache take care of low level encoding (outputting chunk sizes) so all you actually need to do is a flush() once or several times before the end of your output, and the response will be in chunked transfer encoding. And this fits with my experience viewing results in firefox (results gradually load) – Harry Wood Mar 23 '12 at 17:23
4

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:

  1. Check if «implicit_flush» is On in your php.ini
  2. Know if you overflow output buffer («output_buffering» in php.ini) it will flush automatically.
pashak
  • 41
  • 2
2

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.

SBoys3.com
  • 424
  • 3
  • 12
-2

Use ob_flush(); before 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);
        }

?>
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
Partha Pal
  • 300
  • 1
  • 5