views:

148

answers:

2

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.

+3  A: 

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
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
None, besides the potential memory footprint of the webserver, and memory is cheap now.
m1tk4
`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
A: 

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();
zolex
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
@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
@Nirmal, er, yes, duh.
timdev
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...?
zolex
@zolex - The 300 MB memory limit is there for various performance reasons other than just uploading and downloading files.
Nirmal
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 ^^
zolex