00 Votes

PHP: File Download Script

Tutorial by Stefan Trost | 2014-09-16 at 23:06

Today, I would like to show you how to create a little download script using PHP. Later, the script should be callable by just using a normal HTML link.

HTML

In the HTML of our website, we would like to offer the HTML links for downloading the file in the following format.

<a href="download.php?file=test.pdf">Download</a>

With this link, we are opening the PHP script (stored as download.php) and we are passing the variable "file" via GET, here "test.pdf". Of course, you can change the names of the script file, the variable or the link like you want.

PHP

We are writing the following PHP code into the file "download.php".

$file = preg_replace("/[^0-9a-z.\-_ ]/i", "", $_GET['file']);
$file = 'filedir/'.$file;

if (file_exists($file)) {	
  header('Content-Disposition: attachement; filename='.basename($file));
  header('Content-Type: application/force-download');
  header('Expires: 0');
  header('Cache-Control: must-revalidate');
  header('Content-Length: '.filesize($file));
  header('Connection: close');
  
  readfile($file);
} else {
  header("HTTP/1.0 404 Not Found");			
}

First of all, we are catching the variable, we have defined in the link by calling $_GET['file']. In the example, the value is "test.pdf". At this point, it is very very important to ensure that nobody can successfully call the script with a file to which he or she should not have any access. Otherwise by calling something like "download.php?file=../secret.php", everyone could download arbitrary files from our webspace (for example plain text PHP files including passwords etc).

We are doing the trick by only allowing letters, numbers and the characters ".", "-" and "_" in the file name and by attaching a directory ("filedir/") to the name. Of course, in this directory, you should only store files that can be downloaded without any problems (no scripts or other important files).

It would be better to only pass something like a file ID and to call the script in the form "download.php?file=123". You can than retrieve the real file name from a database. You can also use this whenever you want to disguise the directory in which the file is stored and/or the server name of the file. Also if you would like to count the downloads, you can use this way to interact with the database in this step. In the example above, we have made it as easy as possible, so that we have omit the data base part.

When having determined the path of the file, first of all, we are checking whether the file is really existing on the server. If not, we are firing a "404 Not Found", otherwise, we are starting the download.

For the download, first, we are sending some headers to the requesting browser and after that, we are just outputting the content of the file with the PHP function readfile(). Of course, you can adjust this header like you want. I will come to some details of the header in the next section.

Explanation of the Header

The "Content-Type: application/force-download" ensures, that the file is offered as download and that it is not opened in the browser (you can omit this line).

The name stated in the line "Content-Disposition: attachement; filename='.basename($file)", is the name, under which the browser will try to save the file. In the example, we are using basename($file) to derive the filename directly from the passed string, but we can also use any other name here (for example "Content-Disposition: attachement; filename=download.pdf"). With changing this, we can start the download under a different name from the name used on the server.

With "Expires: 0" and "Cache-Control: must-revalidate", we would like to achieve, that the browser is not writing the file into its cache and that always the current file is downloaded.

ReplyPositiveNegative

About the Author

AvatarYou can find Software by Stefan Trost on sttmedia.com. Do you need an individual software solution according to your needs? - sttmedia.com/contact
Show Profile

 

Related Topics

Rename File to its Folder Name

Tutorial | 0 Comments

Important Note

Please note: The contributions published on askingbox.com are contributions of users and should not substitute professional advice. They are not verified by independents and do not necessarily reflect the opinion of askingbox.com. Learn more.

Participate

Ask your own question or write your own article on askingbox.com. That’s how it’s done.