Force File Downloads instead of opening

There are times when you want to host some files but want people to download them instead of getting them opened by the default browser defined action. This situation arises in cases when you are hosting pdf, image or music files.  If you are using WordPress, you may use Download manager plugins for this effect but what happens when you are on a static website. There are .htaccess file hacks or apache tricks to achieve this. But not all webhosting companies allow such mods or hacks. The one hack I am going to tell you will work no matter which webhost you are using and will work on both blogs and static websites as well.

Step 1

First make a empty file and name it as download.php. Paste the following code into it:

<?php
$sourceFile = $_GET['file'];

if( headers_sent() ) 
  die('Headers Sent'); 

if(ini_get('zlib.output_compression')) 
  ini_set('zlib.output_compression', 'Off'); 

if (!is_file($sourceFile)) { die("<b>404 File not found!</b>"); }

$len = filesize($sourceFile);
$filename = basename($sourceFile);
$file_extension = strtolower(substr(strrchr($filename,"."),1));

switch( $file_extension ) {
  case "pdf"  : $ctype="application/pdf"; break;
  case "exe"  : $ctype="application/octet-stream"; break;
  case "zip"  : $ctype="application/zip"; break;
  case "doc"  : $ctype="application/msword"; break;
  case "xls"  : $ctype="application/vnd.ms-excel"; break;
  case "ppt"  : $ctype="application/vnd.ms-powerpoint"; break;
  case ".docx": $ctype="application/vnd.openxmlformats-officedocument.wordprocessingml.document"; break;
  case ".pptx": $ctype="application/vnd.openxmlformats-officedocument.presentationml.presentation"; break;
  case ".xlsx": $ctype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; break;
  case "gif"  : $ctype="image/gif"; break;
  case "png"  : $ctype="image/png"; break;
  case "jpeg" :
  case "jpg"  : $ctype="image/jpg"; break;
  case "mp3"  : $ctype="audio/mpeg"; break;
  case "wav"  : $ctype="audio/x-wav"; break;
  case "mpeg" :
  case "mpg"  :
  case "mpe"  : $ctype="video/mpeg"; break;
  case "mov"  : $ctype="video/quicktime"; break;
  case "avi"  : $ctype="video/x-msvideo"; break;

  //The following are for extensions that shouldn't be downloaded
  case "php"  :
  case "css"  :
  case "js"   : 
  case "htm"  :
  case "html" :
  case "txt"  : die("<b>Cannot be used for ". $file_extension ." files!</b>"); break;

  default     : $ctype="application/force-download";
}

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public"); 
header("Content-Description: File Transfer");
header("Content-Type: $ctype");
$header="Content-Disposition: attachment; filename=".$filename.";";
header($header );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".$len);
@readfile($sourceFile);
exit;

Step 2

Now upload the file to your website … for example I am considering the location as http://www.domain.com/download.php

Step 3

Now for linking to the file you want people to download forcibly, just point their links as http://www.domain.com/download.php?file=Filepath

Now, all files you link to like this will be forced to download from the visitor irrespective of the browser the user uses and of the webhosting you use.

Updated (11 October, 2012): I have updated and fixed the code above. It now supports newer Office file formats and also some video formats as well. Also it won’t allow downloads of html, php, css type files and also does some simple error checks.

8 Comments


  1. a lot helpful…

    thanks!


  2. My file is about 2.5 MB pdf but that is being downloaded is just 522 kb. Same case will all the browsers. Any suggestions.


  3. i know this is an old post, but please update it to add a permitted extensions array. for security purposes, you don’t want people downloading server side scripts.


  4. works great, except for in google chrome.

    Chrome automatically downloads what seems to be the file header (the file exists on the hard drive but has a size of 0 bytes). any clues?


  5. That is a great addition. I’m always frustrated when i’m trying to get a user to download a text file that I have posted and they keep coming back to me saying they can’t download it and that it just opens in a new browser window.

    Thanks for the tip.


  6. That’s a great trick. Nice one. Will try it once now . lets see.


  7. A nifty trick. Saves meddling with the .htaccess file, which, because the latter is essential to WordPress’ operation, is A Good Thing.

Comments are closed.