Force File Download With PHP

19th February 2008 - 3 minutes read time

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.

  1. <?php
  2. $file = $_GET['file'];
  3. header('Content-type: octet/stream');
  4. header('Content-disposition: attachment; filename='.$file.';');
  5. header('Content-Length: '.filesize($file));
  6. readfile($file);
  7. exit;
  8. ?>

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>

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.

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

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.


Great piece of code! Here is a more secure way of doing it though
  1. $file = ($_GET['file'] ="hashbangcode-image.png" ? $_GET['file'] : '');
  3. if(file_exists($file)){
  4. $ext = substr($file,-3);
  5. if($ext=='jpg' || $ext=='gif' || $ext=='png' || $ext=='pdf'){
  6. header('Content-type: octet/stream');
  7. header('Content-disposition: attachment; filename='.$file.';');
  8. header('Content-Length: '.filesize($file));
  9. readfile($file);
  10. exit;
  11. }
  12. }else{
  13. echo 'File not found!';
  14. }
  15. ?
But I guess this is impractical if you want to download dynamic images....

Emmanuel (Mon, 06/28/2010 - 04:51)


Anyone tell me how to get extension of that file

Anyone tell me… (Sun, 11/15/2020 - 12:55)


In the examples above I have used the following to extract the extension of the file.

$ext = substr($file,-3);

However, I have not written it this way for a number of years now. My preferred route is to use the pathinfo() function. This will return information about the file name passed to it. For example.

  1. print_r(pathinfo('docroot/index.php'));

Will print out.

  1. Array
  2. (
  3. [dirname] => docroot
  4. [basename] => index.php
  5. [extension] => php
  6. [filename] => index
  7. )

If you want to get *just* the file extension then you pass in the PATHINFO_EXTENSION flag to the pathinfo() function. Like this.

  1. echo pathinfo('docroot/index.php', PATHINFO_EXTENSION);

This returns a string instead of the full array of file info, so the function now prints this:


I hope that answers your question?

Add new comment

The content of this field is kept private and will not be shown publicly.