0

Am using the code below to download a file. it uses flush() and ob_flush() functions. I read brenns10 comment's at this link

It says that use of flush() and ob_flush() will cause the data to go in memory until it's displayed and as such that its not good for server with limited resources. Am on a shared server.

Please I need an explanation on this. should I flush() and ob_flush() as its in the code below or should I remove it. Thanks

$download_file = '10gb_file.zip';

$chunk = 1024; // 1024 kb/s

if (file_exists($download_file) && is_file($download_file)) {
    header('Cache-control: private');
    header('Content-Type: application/octet-stream');
    header('Content-Length: ' . filesize($download_file));
    header('Content-Disposition: filename=' . $download_file);

    $file = fopen($download_file, 'r');

    while(!feof($file)) {
        print fread($file, round($chunk * 1024));
ob_flush();
        flush();
    }

    fclose($file);
}
chinazaike
  • 517
  • 6
  • 19
  • Are you using `ob_start` anywhere before this code? If not, then `ob_flush` isn't needed. Also `flush` is sorta flakey depending on phps environment. – IncredibleHat Aug 22 '19 at 14:00
  • The question should rather be, should a file of this massive site be downloaded through a PHP script in the first place, and the answer to that is No. – misorude Aug 22 '19 at 14:05

1 Answers1

2

The better option when sending large files is to turn off buffering in PHP and allow your web server or underlying CGI layer to handle it, as they're better equipped to deal with large output streams, with techniques such as writing to temporary files, or delegating it into the socket.

If you have already started an output buffer elsewhere in the code, you would want to first close it using ob_end_clean().

// removes anything which was in the buffer, as this might corrupt your download
ob_end_clean(); 

// sends the file data to the server without trying to copy it into memory
$fp = fopen($download_file, 'rb');
fpassthru($fp);
Mark R
  • 136
  • 2
  • 6
  • thanks, ob_end_clean(); also applies even to packages like Laravel Excel. Exported files were corrupted and adding ob_end_clean(); fixed it. – josevoid Dec 13 '21 at 03:12