How to force downloads with PHP the easy way
Posted in Development, Tutorials by Alex StoiaOften, when you are creating a website, you might want your users to be able to download a file directly from a link and not having to educate the user like “Right-click and select ‘Save As…’ “-scenario
But as you might have noticed, the conventional way is not always working because of the different technologies (browsers,platforms,etc) used. By conventional I mean:
href="music_file.mp3"
The solution to this problem, with php, is a ‘ header soup’ that will help you do this the right way.
Create a file, for ex. download.php, which will handle the download transactions, and insert the following code in it:
<?php header(“Pragma: public”);
header(“Expires: 0″);
header(“Cache-Control: must-revalidate, post-check=0, pre-check=0″);
header(“Cache-Control: public”);
header(“Content-Type: application/force-download”);
header(“Content-Type: application/octet-stream”);
header(“Content-Type: application/download”);
header(“Content-Description: File Transfer”);
header(“Content-Type:”.$_GET['file_extension']);
header(“Content-Disposition: attachment; filename=”.basename($_GET['file_full_path']));
header(“Content-Transfer-Encoding: binary”);
header(“Content-Length: “.sizeOf($_GET['file_full_path']));
@readfile($_GET['file_full_path']);
?>
The header name/content is very intuitive (Cache-Control: must-revalidate, etc) so it’s easy to understand.
Let’s start with the beginning:
The first 4 headers main concern is the cache control (You want the browser to download the file directly from the server not from the cache, proxy-cache ), if they are missing in browsers like ie6 or ie7 you will have problems (it’s actually a bug fix for their http protocol implementation);
-header(“Pragma: public”) // relevant only for IE6
-header(“Expires: 0″) // cache expiration time for a file
-header(“Cache-Control: must-revalidate, post-check=0, pre-check=0″); // you’re telling the cache that you want it to strictly follow your rules.
-header(“Cache-Control: public”) // marks authenticated responses as cacheable
The next 3 headers build the Force Download dialog:
-header(“Content-Type: application/force-download”);
-header(“Content-Type: application/octet-stream”);
-header(“Content-Type: application/download”);
We inform the browser that a file transfer will be initiated header(“Content-Description: File Transfer”); and the file type/extension header(“Content-Type:”.$_GET['file_extension']);
header(“Content-Disposition: attachment; filename=”.basename($_GET['file_full_path'])) forces the browser to display the download dialog and attaches a name to the file that waits to be downloaded.
I used basename($_GET['file_full_path']), to avoid another IE bug..if the name contains special characters like “/” the downloaded file name will be the actual php file ( in my case download.php…IE HAZZARD…and when you open it, you will get unmapped bytes, because of the wrong extension ).You can also put a custom name, but be careful to put the right extension.
-header(“Content-Transfer-Encoding: binary”) , means that no encoding is used
-header(“Content-Length: “.sizeOf($_GET['file_full_path'])), this entity-header field indicates the size of file, in decimal number of octets
And finally the @readfile($_GET['file_full_path']); witch reads a file and writes it on the output buffer.(mapped and encapsulated, in the download context).
I used the parameters (file_full_path, file_extension) as $_GET, because I usually use this download code in a separate file, as presented, because doing so I can avoid the “Headers already sent..” warning, and before I redirect the data to this file (GET or POST) I can process it.
NOTE: file_full_path – the relative path of the file ($_GET['file_full_path']=’ /music/music_file.mp3′)
Related Entries
About the author
-
http://www.namakusurya.com Surya Adi Sapoetra
-
http://www.topgeldzaken.nl/lenen-zonder-bkr-toetsing/ lenen
-
http://www.laptopspark.com laptopspark
-
http://www.laptopspark.com laptopspark
-
http://www.webdesigner.co.in Kate Brown
Sponsors
Recent Comments
- Ansh on FancyPlayer Revisited – jQuery Fancybox and Flowplayer Complete Integration
- Published Articles on Inspiration: The Art Of Luke Lucas
- Fast Business Loan on Create a Glass Text effect in Photoshop
- Fast Business Funding on Inspiration: The Art Of Luke Lucas
- Fast Business Funding on Create a live-update list effect with jQuery
Recent Posts
- Inspiration: The Art Of Fredy Santiago
- Freebie: Complete Web UI Kit for your next design
- Inspiration: The Art Of Rob Shields
- Freebie: Aluminium UI Buttons
- Inspiration: The Art Of Maxime Archambault

