If you ever wanted to serve big or many files through PHP and needed to check permissions or do any other calculation upfront file delivery, you might want to think about an Apache module called mod_xsendfile. With it you’re able to separate permission checks and other script related stuff from the slow part of file delivery in which PHP is not best at.
And getting it up and running is pretty simple.
a2enmod xsendfile
apache2ctl restart
Now, in your virtual host configure your host to pick up the module and maybe define a folder wich the module is allowed to send files from.
#enable the module for your host
XSendFile On
#define a white list folder outside your DocumentRoot
XSendFilePath /some/path/outside/my/docroot
That’s it on the Apache side of things.
Now, simply tell Apache to handle the file transfer itself in your script. This is done by sending the X-Sendfile-Header. No more needs to be done. No file reading, nothing. The whole delivery is being delegated to Apache.
//some code to check permissions, get the file name, rescue the world or whatever
//...
header('X-Sendfile: '.$absolute_path_to_file);
header ('Content-Type: application/octet-stream');
header ('Content-Disposition: attachment; filename='.$some_file_name );
exit();
And that’s it. Now all your validation stuff will be done by PHP while file delivery is done by Apache.