Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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

1 Answer 1

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

memory_limit=32M

Either raise that, or spool the file in smaller chunks

<?php 
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
1  
Makes it easier to change later, 1*(1024*1024) == 1Mb, 16*(1024*1024) == 16Mb –  Dave Cheney Feb 25 '10 at 20:12

Your Answer

 
discard

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.