Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Trying to force-download file with PHP using usual:

header("Content-type: $type" );
header("Content-Disposition: attachment; filename=$name");
header('Content-Length: ' . filesize($path));

And it does successfully for files somewhere below 32 mb. For bigger ones it just returns zeroed file.

Obviously there's some kind of limit, but what sets it? Using Apache 2.2.11 and PHP 5.3.0.

I asked this question on stackoverflow but they said that it better fits here. I'm not personally sure since I do not know what causes it in first place. Maybe it's Apache?

share|improve this question
Is there anything in the apache error.log ? – Dave Cheney Feb 24 '10 at 14:01
up vote 0 down vote accepted

readfile() buffers the entire file in memory before streaming it back to the client. In your php.ini you've probably got


Either raise that, or spool the file in smaller chunks

function readfile_chunked ($filename) { 
  $chunksize = 1*(1024*1024); // how many bytes per chunk 
  $buffer = ''; 
  $handle = fopen($filename, 'rb'); 
  if ($handle === false) { 
    return false; 
  while (!feof($handle)) { 
    $buffer = fread($handle, $chunksize); 
    print $buffer; 
  return fclose($handle); 
share|improve this answer
Got that figured out on stackoverflow. Thanks for your response. What makes me wonder though (I've seen similar expression around the web) - what is the point of 1 in 1*(1024*1024), since it doesn't change anything? – jayarjo Feb 25 '10 at 12:10
Makes it easier to change later, 1*(1024*1024) == 1Mb, 16*(1024*1024) == 16Mb – Dave Cheney Feb 25 '10 at 20:12

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.