Developers experience issues while downloading large files using PHP, there are no of possible things to cause issue, i.e incorrect headers for browsers or incorrect file streaming.
Lets see how the correct headers are passed and how the large files are streamed in chunks
Note: Best practice is to zip your file/contents.
Lets talk about headers
You need to send correct headers to browser
//path to your orignal file $file = "/home/xyz/file-to-download.zip"; //will be downloaded as "documents.zip" to users, you can use original name as well. $downloadName = "documents.zip"; //telling browser that the content type is zip file header('Content-Type: application/zip'); //telling browser about correct length of file in bytes header('Content-Length: ' . filesize($file)); //tell browser to download it header('Content-Disposition: attachment; filename="' . $downloadName . '"'); //handle caching header('Pragma: public'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Cache-Control: private', false); //tell browser the encoding of file header('Content-Transfer-Encoding: binary');
Once header part is done we move to reading file in chunks of bytes and sending those chunks instantly to browser, in other words streaming the file.
//set download speed in bytes $bitrate = 1024; //1024 bytes = 1Kb //how much bytes to read in a chunk $chunkSize = $bitrate * 1024; //open file for reading in binary mode $handle = fopen($file, 'rb'); //read file chunks by chunk and send output to browser until end of file is not reached while (!feof($handle)) { //read chunk of a file echo fread($handle, $chunkSize); //send an application-initiated buffer ob_flush(); //usually FastCGI has a socket buffer on its own so use flush() to send the current content. flush(); } fclose($handle);
You can use $bitrate variable to control the speed of download for example
//set speed to 100kb $bitrate = 100;
Hi, this code works like a charm, but after download a 11GB file, it warns me the file is corrupted.
I tested the same file before upload to server, and it’s totally fine.
Do you have any idea how to solve it?
Thanks in advance.
Rodrigo
Have you tested it with a smaller file on your server?
Here are steps to test.
1. Test it with smaller file if that is also corrupt then download that file using ftp and see if that is fine. If file downloaded by ftp is also corrupt that means there is something wrong at file uploading.
2. If the file downloaded by ftp seems fine then there might be spaces in download script, you can use ob_end_clean to clean up buffer before starting download.