Chunked transfer encoding with Php

Chunked transfer encoding with Php © ba1969@sxc.hu

Few days ago I played with my Symfony2 project and tried to implement chunked transfer of data to the browser / web service client.

So, what is chunked transfer encoding anyway?

I will use little trick here and put link to Wikipedia article: Chunked transfer encoding

There are some advantages and also there are some disadvantages for that kind of response.

Advantage:
With that kind of response, if you serving large data to the client and needs some time to generate response, you can use chunked transfer encoding for sequentially returning data to the client, so client doesn’t have to wait whole data is generated, buffered on server and then returned, but client gets chunks of data one by one, so, client almost immediately sees the data coming from server.

Disadvantage:
When using this kind of approach, you send headers to the client immediately with status code 200. In meantime when some exception happens while parsing or getting data to serve, you can not return different header (for example 400 or something) to client with appropriate message, because you already sent your header with success response…

In few words, basic mechanism is simple:

1. Send header with ‘Transfer-encoding: chunked’
2. Get data from database or echo some data respecting chunked response format (chunk length – chunk data – I used  ‘dump_chunk’ function in below code for that function for that)
3. Flush php buffers for each ‘chunk’ you want to send to the browser

There are many variations on properly handling that kind of response, but I will mention something I tried in Symfony2 project:

//some Symfony2 controller.php
 
//...
public someFunctionInsideController()
{
   $response = new Response();
   $response->headers->set('Content-Encoding', 'chunked');
   $response->headers->set('Transfer-Encoding', 'chunked');
   $response->headers->set('Content-Type', 'text/html');
   $response->headers->set('Connection', 'keep-alive');
   $response->sendHeaders();
   flush();
   ob_flush();
 
   for ($i = 0; $i < 1000; $i++) {
      $this->dump_chunk('Sending data chunk ' . ($i+1) . ' of 1000 <br />');
      flush();
      ob_flush();
      sleep(2);
   }
 
   return new Response();
}
//...
 
//I found this on some forum / article and seems to be useful
//Also I would like to give some credits to the author, but I don't really know where I dig this:
private function dump_chunk($chunk) {
   echo sprintf("%x\r\n", strlen($chunk));
   echo $chunk;
   echo "\r\n";
}

I hope this article you will find this article useful for something in your code… 🙂

You made it all the way down here so you must have enjoyed this post! You may also like:

How to setup http protocol with SSL on LAMP environment Mladen Lotar
Mladen Lotar, | 3

How to setup http protocol with SSL on LAMP environment

2 comments

  1. Thanks for sharing. I do have some questions about it:
    1. Shouldn’t the chunk size be in hexadecimal format?
    2. Shouldn’t you send the terminating chunk with the final byte 0?

  2. Can you provide description for handling chunked data for a request with keep alive. because in php after the read functions reads all data from the response it still waits to read data but the server will no have any data to send. Is it only in php that we cannot know where the end of the message is?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.

Tell us about your project

Drop us a line. We'd love to know more about your project.