So we want to allow visitors to the site to download files, but would either like to restrict this to those logged in, track/count download times, or do something else interesting….
If we use a PHP page to do this, we can add all of our usual functionality at the top, and then get the page to display the file (or download) if the criteria is met, an error message or re-direct if not…
I won’t cover the ‘check login’ or ‘track/count’ codes here, just the bit that actually handles the file….
Create a page named, downloads.php and add the following:
<?php if(isset($_GET['file'])){ // Get the file name from URL $filename = trim($_GET['file']); // Get the file extension from the filename $file_extension = strtolower(substr(strrchr($filename,"."),1)); // Set the paths for your files $file_path = $_SERVER['DOCUMENT_ROOT'].'downloads/'.$file_extension.'/'.$filename; // Use switch to set the settings switch($file_extension){ case "pdf": $show=1; $ctype="application/pdf"; break; case "exe": $show=0; $ctype="application/octet-stream"; break; case "zip": $show=0; $ctype="application/zip"; break; case "doc": $show=0; $ctype="application/msword"; break; case "xls": $show=0; $ctype="application/vnd.ms-excel"; break; case "ppt": $show=0; $ctype="application/vnd.ms-powerpoint"; break; case "rtf": $show=0; $ctype="application/rtf"; break; case "gif": $show=1; $ctype="image/gif"; break; case "png": $show=1; $ctype="image/png"; break; case "wav": $show=0; $ctype="audio/wav"; break; case "mp3": $show=0; $ctype="audio/mpeg3"; break; case "wmv": $show=0; $ctype="video/x-ms-wmv"; break; case "avi": $show=0; $ctype="video/avi"; break; case "asf": $show=0; $ctype="video/x-ms-asf"; break; case "mpg": $show=0; $ctype="video/mpeg"; break; case "mpeg": $show=0; $ctype="video/mpeg"; break; case "jpeg": case "jpg": $show=0; $ctype="image/jpg"; break; default: $show=0; $ctype="application/force-download"; } // Create Output if(isset($_GET['showVars'])){ // Create a test mode echo '<p>$filename: '.$filename.'</p>'; echo '<p>$file_extension: '.$file_extension.'</p>'; echo '<p>$file_path: '.$file_path.'</p>'; echo '<p>$show: '.$show.'</p>'; echo '<p>$ctype: '.$ctype.'</p>'; } else { // Create Headers and display/download the file header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: must-revalidate"); header("Content-Type: $ctype"); if($show==0){ header("Content-Disposition: attachment; filename=\"".$filename."\";" ); } header("Content-Transfer-Encoding: binary"); header("Content-Length: ".filesize($filename)); readfile($file_path); exit(); } } else { echo '<p>No file specified!</p>'; } ?>
All you need to do is create a link to your downloads.php page, with the file name at the end, like: downloads.php?file=test.jpg and you’re off…
If that’s too ugly, save the file as index.php and pop it in a downloads folder, so its: downloads/?file=test.jpg
You’ll notice I’ve added a ‘test’ mode so you can check where the script is trying to find the files and the values that are created. Use downloads.php?file=test.jpg&showVars to show the vales set.
By default, it’s looking at the root directory of your site, then for a folder called ‘downloads’ and inside there, it’s looking for a folder the same name as the file extension, then the file name,
i.e. www.yoursite.co.uk/downloads/jpg/test.jpg
In the script, inside the ‘switch’, you’ll see $show=1 and $show = 0, this lets you choose to show the file in the browser or to prompt the download box, so you can show an image, but trigger a download for larger files, .doc, .exe, .zip, etc…