Correct headers for file downloads

Most of the time on websites you will simply link directly to a file if you want to allow visitors to download it. However, there are two occasions when you might want to link to a script which outputs the content of the file to the browser:

  1. The file is generated dynamically each time it is requested – e.g. if you want a timestamp to appear on it.
  2. Access to the file is restricted – e.g. only users with certain privileges can download it.

The simplest way to output the contents of a file is to use either echo or print, and if the file already exists on disk (outside the document root) you can use file_get_contents like so:

echo file_get_contents('/path/to/file.txt');

However, this method will not always produce the desired result for users of Internet Explorer, especially if you are running a HTTPS site. In order for the download to work correctly, you need to send the following headers before the echo statement:

Cache-control: Private
Content-Type: application/octet-stream
Content-Dispoition: attachment; filename="file.txt"
Pragma: Public

Don’t ask me why all those headers are required — I spent the best part of an afternoon trying various combinations until I found one which worked!

The headers above will force the browser to prompt the user to save the file with a suggested name of ‘file.txt’ (you can of course change this). If you would prefer the file to be displayed within the browser or be automatically opened with the correct program, you need to change the Content-Type line to use the correct type for the file — a few examples include:

  • Excel spreadsheets: application/
  • Word documents: application/msword
  • PDF files: application/pdf

If you’re not sure of the correct content type to use, a quick search should find the answer, or the definitive list can be found at IANA.


No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.