Skip to main content

Konstantinos Loupasakis

How to efficiently trigger file downloads in PHP

Making a download happen in PHP is dead simple: Just set your Content-Type and send it’s contents to the client through the standard output, usually with the use of echo.

Here is what you want to avoid when you try doing that.

Here is how I used to do it:

header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: Binary');
header('Content-disposition: attachment; filename="' . basename($file_location) . '"');
echo file_get_contents($file_location);

This might work fine for small files but there is a caveat: It will load the entire file to memory, which sooner or later will bring your server to it’s knees.
Here is a more memory-efficient way to do it.

header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: Binary');
header('Content-disposition: attachment; filename="' . basename($file_location) . '"');
readfile($file_location);

The difference between the two snippets is a subtle, but important one: file_get_contents returns all the contents of the file into a single string. Which, in turn, means that if our file is, say 1GB, we have used 1GB of our server RAM just so that we can echo our file.

readfile on the other hand echoes the files, without having to load the entire thing in memory; it internally goes through the file and echoes it’s contents with minimal memory footprint.