0

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?

jayarjo
  • 337
  • 1
  • 3
  • 12

1 Answers1

0

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); 
} 
?>
Dave Cheney
  • 18,567
  • 8
  • 49
  • 56
  • 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