Reputation: 2170
I am trying to force a download using php headers and the readfile function, here is my code:
if(file_exists($file_url)){header('Content-Type: '.$ftype);
header('Content-Transfer-Encoding: binary');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header("Content-Length: " . filesize($dir.$fname));
header("Content-disposition: attachment; filename=\"".$fname."\"");
ob_clean();
flush();
readfile($dir.$fname);
exit;}
The issue is that files greater then 37mb are downloading at 0 bytes. I have checked the php config and memory_limit
is set to 200mb, I have tried downloading in chunks with this:
$filename = $dir.$fname;
$filesize = filesize($filename);
$chunksize = 4096;
if($filesize > $chunksize)
{
$srcStream = fopen($filename, 'rb');
$dstStream = fopen('php://output', 'wb');
$offset = 0;
while(!feof($srcStream)) {
$offset += stream_copy_to_stream($srcStream, $dstStream, $chunksize, $offset);
}
fclose($dstStream);
fclose($srcStream);
}
else
{
// stream_copy_to_stream behaves() strange when filesize > chunksize.
// Seems to never hit the EOF.
// On the other handside file_get_contents() is not scalable.
// Therefore we only use file_get_contents() on small files.
echo file_get_contents($filename);
}
But instead of forcing the download it displays the file. Any ideas?
Upvotes: 0
Views: 534
Reputation: 2858
Try with this.
header ("Content-Disposition: attachment; filename=".$filename."\n\n");
header ("Content-Type: application/octet-stream");
@readfile($link); // Path to file
Upvotes: 0
Reputation: 2170
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;
}
header('Content-Type: '.$ftype);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header("Content-Length: " . filesize($dir.$fname));
header("Content-disposition: attachment; filename=\"".$fname."\"");
readfile_chunked($filen);
Upvotes: 1