5

While setting up an online file management system, and now I have hit a block.

I am trying to push the file to the client using this modified version of readfile:

function readfile_chunked($filename,$retbytes=true) { 
   $chunksize = 1*(1024*1024); // how many bytes per chunk 
   $buffer = ''; 
   $cnt =0; 
   // $handle = fopen($filename, 'rb'); 
   $handle = fopen($filename, 'rb'); 
   if ($handle === false) { 
       return false; 
   } 
   while (!feof($handle)) { 
       $buffer = fread($handle, $chunksize); 
       echo $buffer; 
       ob_flush(); 
       flush(); 
       if ($retbytes) { 
           $cnt += strlen($buffer); 
       } 
   } 
       $status = fclose($handle); 
   if ($retbytes && $status) { 
       return $cnt; // return num. bytes delivered like readfile() does. 
   } 
   return $status; 
}

But when I try to download a 13 MB file, it's just breaking at 4 MB. What would be the issue here? It's definitely not the time limit of any kind because I am working on a local network and speed is not an issue.

The memory limit in PHP is set to 300 MB.

Thank you for any help.

Community
  • 1
  • 1
Nirmal
  • 9,391
  • 11
  • 57
  • 81
  • 2
    There's almost certainly something in the error log, assuming you've got it turned on. Check that and amend the question. – timdev Jun 01 '10 at 01:19
  • Nope. Nothing relating to this in the error log. All I have is some deprecation warnings from different scripts. – Nirmal Jun 01 '10 at 01:23
  • What client are you using to dopwnload the content? Does the behaviour change if you use a different client? My Guess would be that the agent you are using can't cope with large chunked encoding. Try a different client / and /or sniffing the traffic. – symcbean Jun 01 '10 at 08:57
  • @symcbean - I tried using both IE and Chrome, and both are responding the same way. If they can't handle the chunked encoding, they shouldn't be taking the first 4 MB, I believe. And, how to sniff the traffic? Haven't done that before. Thanks! – Nirmal Jun 02 '10 at 10:49
  • an excellent packet sniffer is [Wireshark](http://www.wireshark.org/). Check to see whether data is still streaming after the error, and check to see whether any error messages are being sent back that for some reason you're not seeing. – eykanal Jun 02 '10 at 18:05

2 Answers2

4

Most likely you are hitting the response buffer limit set by your webserver. IIS and FastCGI are known to have 4mb as the default buffer size. I would start your search with looking into the webserver<->PHP SAPI configuration.

m1tk4
  • 3,439
  • 1
  • 22
  • 27
  • Is there any other drawback in increasing the buffer limit? Will setting it to, say, 50 MB create a problem for general browsing experience? Thanks for any insight. – Nirmal Jul 28 '10 at 04:34
  • None, besides the potential memory footprint of the webserver, and memory is cheap now. – m1tk4 Jul 28 '10 at 13:25
  • `Note:` I wish I had more answers for the question, but since the bounty was about to end, had to give it to this answer. – Nirmal Sep 28 '10 at 04:59
1

do NOT flush your output but try to buffer it and then send it to teh client in one piece.

ob_clean(); // in case anything else was buffered
ob_start();

// do read/echo operations

ob_end_flush();
Andreas Linden
  • 12,489
  • 7
  • 51
  • 67
  • Why would he do that? The whole point of using the replacement readline() function is to avoid reading the whole file into PHP's memory space at once. Your answer completely defeats that purpose. – timdev Sep 23 '10 at 19:45
  • @timdev - Did you mean `readfile()` function? Yes, you are right. Sending the file as a one whole piece is what we want to avoid here. – Nirmal Sep 24 '10 at 05:07
  • well then your question is not precise enough, for me it looked like you wanted to avoid reading the file in on piece from teh filesystem. and btw why do you have 300MB memory limit then...? – Andreas Linden Sep 25 '10 at 00:28
  • @zolex - The 300 MB memory limit is there for various performance reasons other than just uploading and downloading files. – Nirmal Sep 25 '10 at 05:15
  • for performance reasons? yes it will really charge your server when a script goes mad ^^ 300mb for a web frontend application is way too much ^^ – Andreas Linden Sep 25 '10 at 15:13