1. Use headers correctly
This is a very widespread problem and unfortunately even the PHP manual is plagued with errors. Developers usually say “this works for me” and they copy stuff they don’t fully understand.
First of all, I notice the use of headers like Content-Description and Content-Transfer-Encoding. There is no such thing in HTTP. Don’t believe me? Have a look at RFC2616, they specifically state “HTTP, unlike MIME, does not use Content-Transfer-Encoding, and does use Transfer-Encoding and Content-Encoding“. You may add those headers if you want, but they do absolutely nothing. Sadly, this wrong example is present even in the PHP manual.
Second, regarding the MIME-type, I often see things like Content-Type: application/force-download. There’s no such thing and Content-Type: application/octet-stream (RFC1521) would work just as fine (or maybe application/x-msdownload if it’s an exe/dll). If you’re thinking about Internet Explorer, it’s even better to specify it clearly rather than force it to “sniff” the content. See MIME Type Detection in Internet Explorer for details.
Even worse, I see these kinds of statements:
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
The author must have been really frustrated and added three Content-Type headers. The only problem is, as specified in the header() manual entry, “The optional replace parameter indicates whether the header should replace a previous similar header, or add a second header of the same type. By default it will replace“. So unless you specify header("Content-Type: some-value", FALSE), the new Content-Type header will replace the old one.
2. Forcing download and Internet Explorer bugs
What would it be like to not having to worry about old versions of Internet Explorer? A better world, that’s for sure.
To force a file to download, the correct way is:
header("Content-Disposition: attachment; filename=\"$file_name\"");
Note: the quotes in the filename are required in case the file may contain spaces.
The code above will fail in IE6 unless the following are added:
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
Now, the use of Cache-Control is wrong in this case, especially to both values set to zero, according to Microsoft, but it works in IE6 and IE7 and later ignores it so no harm done.
If you still get strange results when downloading (especially in IE), make sure that the PHP output compression is disabled, as well as any server compression (sometimes the server inadvertently applies compression on the output produced by the PHP script).
Look at this,
.mp3 audio/mpeg3
.mp3 audio/x-mpeg-3
.mp3 video/mpeg
.mp3 video/x-mpeg
See this link for more info.
Using Content-Disposition: attachment... forces a download box to appear instead of having to right click -> save target as.