So I’m making a list of files that are held on the web server that are available for download. What happens when links to these files are clicked on depends on how the clients browser is set up. For example if you click on a link to a .JPG file it will probably load up within the browser window from which the link clicked. However, you could change this so that whenever you click on a link to a .JPG it would load in, say, Photoshop. This is all well and good and is how the web has worked since the beginning. It means you can set up your browser to deal with whatever you want, however you want.
The trouble comes when the default action is not the one you want. For example, what if I’ve got a load of JPGs on my site which I would like people to be able to download rather than just open? Or a bunch of html files? Anyone can click the link and the links and the file will load in the browser window. They can then go “file > save file as” or right click on the image and save it, but that’s not very elegant. So what’s the elegant way?
Have you ever gone to download a file from a website and instead of a link to the file you get a link to “download.php” or something similar? Probably with some kind of querystring after it, like “download.php?fileid=5456”. Ever wondered why people do this? Now can you guess why?
Here’s how you do it. Create a new page called download.php or something suitable. Put this magic code on it:
header("Content-disposition: attachment; filename=".$file_name); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header('Content-type: application/force-download'); readfile($file_name);
(Assuming $file_name is a string containing the address of the target file.)
One word of warning:
Some more words of more serious warning:
Don’t do this:
If you do someone could potentially alter it so that it does something like this instead:
And all of a sudden they’ve got your important php file which has all your database passwords, bank details, national insurance numbers and locations of your childrens schools. You don’t want that. A better way of doing it would be:
Then use the id to lookup the file name and then go and get it.
One Other Note:
The @ Symbol
If you put this at the beginning of a line it suppresses any error messages which may otherwise appear.