Force File Download With PHP

When you supply files that web browsers can open they are usually opened inside the browser, rather than being downloaded. This can be annoying, especially where PDF documents are involved. You could supply the files in a compressed format in order to force users to download them, but this is also annoying as the user then has to uncompress the file.

You can force the web browser to supply the file as a download by using the header() function in PHP. The following little bit of code will take any filename and supply it as a download.

<?php
$file = $_GET['file'];
header('Content-type: octet/stream');
header('Content-disposition: attachment; filename='.$file.';');
header('Content-Length: '.filesize($file));
readfile($file);
exit;
?>

All you have to do is link to this script with the argument being the file name you want your users to be able to download.

<a href="force.php?file=hashbangcode-image.png" title="Download">PNG Image</a>

Here is an example link that downloads an image.

The benefit of doing things this way means that you can also put some tracking elements into the start of the file to record what and when the file was downloaded.

However, be very careful here. In it's current state the script will allow users to download ANY file within the directory you have the script in, just by supplying the name. This is a big security feature as a use could get hold of your database password file quite easily. To get around this you can restrict the file type to either jpg, gif, png or pdf by using the following code.

<?php
$file = $_GET['file'];
$ext = substr($file,-3);
if($ext=='jpg' || $ext=='gif' || $ext=='png' || $ext=='pdf'){
 header('Content-type: octet/stream');
 header('Content-disposition: attachment; filename='.$file.';');
 header('Content-Length: '.filesize($file));
 readfile($file);
 exit;
}
?>

Finally, it is best to check to see if the file exists before trying to get users to download it. It is doesn't then they will get a file full off PHP error codes.

<?php
$file = $_GET['file'];
if(file_exists($file)){
 $ext = substr($file,-3);
 if($ext=='jpg' || $ext=='gif' || $ext=='png' || $ext=='pdf'){
  header('Content-type: octet/stream');
  header('Content-disposition: attachment; filename='.$file.';');
  header('Content-Length: '.filesize($file));
  readfile($file);
  exit;
 }
}else{
 echo 'File not found!';
}
?>

Share:

  • Add news feed
  • Bookmark this on Delicious

Comments

Restrict Download to Specific File

Great piece of code! Here is a more secure way of doing it though
<?php
$file = ($_GET['file'] ="hashbangcode-image.png" ? $_GET['file'] : '');

if(file_exists($file)){
 $ext = substr($file,-3);
 if($ext=='jpg' || $ext=='gif' || $ext=='png' || $ext=='pdf'){
  header('Content-type: octet/stream');
  header('Content-disposition: attachment; filename='.$file.';');
  header('Content-Length: '.filesize($file));
  readfile($file);
  exit;
 }
}else{
 echo 'File not found!';
}
?>
But I guess this is impractical if you want to download dynamic images....

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <h2> <h3> <h4> <h5> <h6> <pre> <span> <p> <br />
  • Syntax highlight code surrounded by the {syntaxhighlighter SPEC}...{/syntaxhighlighter} tags, where SPEC is a Syntaxhighlighter options string or "class="OPTIONS" title="the title".

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.