Simple and Secure PHP Download Script with Limits Tutorial

You might need to offer some of your website’s content for downloading. For example, many sites commonly offer downloads of PDF and MP3 files. If you do this, you’ll want to set up your download system so that it can give you certain information and perform certain tasks, like telling you how often certain files have been downloaded or limiting the number of downloads. This article will show you how to create a download script that accomplishes this and more.

For an updated version of this article, please visit: Optimize File Loading in PHP

The download script we’ll create in this article lets you perform the following tasks:

  1. Track the number of downloads for particular items, so that you will know the popularity of your downloaded content.
  2. Record the IP address of the user for geo-location purposes. You will know from what countries most users download your content.
  3. Limit the number of downloads to prevent some kinds of download abuse that consume a lot of bandwidth (leading to denial-of-service attacks).
  4. Authenticate the user during downloading, making sure that the user comes from one of your domain pages.
  5. Prevent any user from directly downloading the content using a browser (this is also known as "direct file downloading"). This method will bypass the script and directly enter the file path in the browser. This can be prevented.

Download Script Flow Chart

Below is the download script flow chart that implements the above desired functionality:

First the user visits the download page. The PHP will set the session key for the user. When the user clicks the download link, it will be handled by the PHP download script.

The first thing the script will do is authenticate the user downloading the content. This is done by checking the session key and the referring page. Checking by referrer alone is not effective, as it can be spoofed. Although nothing is 100% secure, layered security (a combination of both methods) and use of HTTPS to encrypt sessions is recommended.

Once the user is authenticated, PHP will get the user IP address and compare it to the existing records in the MySQL database. If the user is a fresh downloader, the script will allow the user to download the content, and then record the user IP in the database.

If the user already has some records in the database, the script will check to see if the user has downloaded not more than three times (which is the number of downloads limit used in this tutorial). If there are less than three download records, the script will allow the user to download the content, and then update its records in the MySQL database.

Finally, if the user has downloaded the content three times already, the script will deny the download and redirect back to the original page.

Create MySQL database for storing user IP addresses

You need to use a database to store users’ IP addresses. The following is the information you need to create the database table:

You can use phpMyAdmin to create the database table. The above screen shot shows that:

Database table name: downloads

Database table field 1: ipaddress which is using varchar(15) type

Database table field 2: downloadtimes which is using int(1) type

It is important to take note of the following database information, which you will need in your PHP script:

  • Database username
  • Database password
  • Database hostname
  • Database table name

The Download Material, Folder and Download link

Below is the important preparation you need to do:

1. Create a folder in your web server that contains the content to be downloaded (e.g ebookdownloads).

2. Change the file permission of the directory to 755.

3. Upload the content for downloading to that folder (e.g. ebook.pdf).

4. This folder will not be publicly visible during the downloading process, so your user will not have an obvious idea as to where the files are saved. Even if they managed to learn the path, any direct downloading will be denied by the server (details below).

5. Upload .htaccess inside this protected folder containing the content for downloading. The htaccess should force downloading of the content type (for example, if it is a PDF file) as well as prevent direct file downloading and any forms of hot linking. Below is the content of the .htaccess:

<Files thisisyourprotectedfile.pdf>
  order deny,allow
  deny from all
</Files>

<Files *.pdf>
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</Files>

6. The recommended file permission for .htaccess and the file for downloading is 644.

7. On the page where you need to present the download link, you can use this code below:

<a rel="nofollow" href="http://www.yourdomain.com/download.php">Download this Content</a>

Let’s name our download script "download.php." It needs to be uploaded to the root directory of your website. Aside from using the anchor text "Download this content," you can also use a download button/image link to make it look attractive and prominent to the user.

8. On the download page where you are presenting the download link to the user, you need to place the session key script at the top most part of the page. The page where you will need to show the download link should execute a PHP script or have a .php extension.

<?php
session_start();
$key= ‘This is your example key, please change this.’;
$_SESSION['key'] = md5($key);
?>

Since this is a PHP script, the download page should support PHP and not be a pure HTML page.

{mospagebreak title=The PHP Download Script (download.php)}

Below is the complete PHP download script (download.php):

<?php

//Start PHP session because you need to compare the session received if it is using correct key.

session_start();

//Get referer

$referer = $_SERVER['HTTP_REFERER'];

//Define the correct session value, the value of $pass should be the same with $key as discussed in the previous section no.8.

$keymatch= $_SESSION['key'];
$pass=’This is your example key, please change this.’;
$md5value= md5($pass);

//Validate user by checking if the user has correct session set and referring page

if (($referer=="http://www.yourdomain.com/thisisyourdownloadpage.php")&& ($keymatch==$md5value)) {

//User is valid, connect to MySQL database

$username = "Your MySQL database username";
$password = "Your MySQL database password";
$hostname = "Your MySQL database hostname";
$database = "Your MySQL database name";
$dbhandle = mysql_connect($hostname, $username, $password)
or die("Unable to connect to MySQL");
$selected = mysql_select_db($database,$dbhandle)
or die("Could not select $database");

//Get the IP address of the user

$ipdownloader= $_SERVER['REMOTE_ADDR'];

//Sanitize input

$ipdownloader = mysql_real_escape_string($ipdownloader);

//check if the user already downloaded before

if (!($fetch = mysql_fetch_array( mysql_query("SELECT `ipaddress` FROM `downloads` WHERE `ipaddress`=’$ipdownloader’")))) {

//No records found, fresh downloader
//Prepare content for downloading

//Define the content type and show force download attachment dialog

header("Content-type:application/pdf");
header(‘Content-Disposition: attachment; filename="http://www.yourdomain.com/ebookfordownloads/ebook.pdf"’);

//Stream the PDF file for downloading using PHP readfile function
//The readfile is using absolute server path
//You can determine this path by uploading a php script to the folder containing the download material.
/*
<?php
echo $_SERVER['SCRIPT_FILENAME'];
?>
*/
readfile("/your/absolute/server/path/html/ebookfordownloads/ebook.pdf");

 

//Record downloader IP address to MySQL database and set download to 1

$firstdownload=1;
mysql_query("INSERT INTO `downloads` (`ipaddress`,`downloadtimes`) VALUES(‘$ipdownloader’,'$firstdownload’)")
or die(mysql_error());
}
else {

//Already has downloading records; check how many times the user downloaded the ebook

$result = mysql_query("SELECT `downloadtimes` FROM `downloads` WHERE `ipaddress`=’$ipdownloader’")
or die(mysql_error());
$row = mysql_fetch_array($result)
or die("Invalid query: " . mysql_error());
$downloadtimes = $row['downloadtimes'];
if ($downloadtimes < 3) {

//the user downloaded less than 3 times, the user still eligible to download the ebook. Stream the PDF to the user for force downloading.

header("Content-type:application/pdf");
header(‘Content-Disposition: attachment; filename="http://www.yourdomain.com/ebookfordownloads/ebook.pdf"’);
readfile("/your/absolute/server/path/html/ebookfordownloads/ebook.pdf");

//Update download records of the user by incrementing it with 1

$updateddownloadtime = $downloadtimes + 1;

//Update download times information of the user in MySQL database

mysql_query("UPDATE `downloads` SET `downloadtimes` = ‘$updateddownloadtime’ WHERE `ipaddress` = ‘$ipdownloader’")
or die(mysql_error());
}
else {

//The user already exceeds the downloading limit, prevent downloading
//destroy session for the user

session_destroy();

//Redirect the user back to the previous page using meta refresh.

echo "<meta http-equiv=’refresh’ content=’0;url=http://www.yourdomain.com/thisisyourdownloadpage.php’>";
}
}

//Close the MySQL database connections

mysql_close($dbhandle);
}
else {

//Invalid user -fails during user authentication, either bad wrong session key or referring page.

//Destroy any session.

session_destroy();

//Redirect the user back to the download page.

echo "<meta http-equiv=’refresh’ content=’0;url=http://www.yourdomain.com/thisisyourdownloadpage.php’>";
}
?>

Implementation Tips

Below are the recommended tips for implementation:

  1. You can download the complete PHP script here: http://bit.ly/eCnDvZ 
  2. Define an upload folder where your content is placed, and add a download link to your download page (details in the previous section); also, upload the required htaccess.
  3. Put your own database connection parameters and download path in the download.php script.
  4. Upload the download.php script to the root directory of your website.
  5. You can view the number of unique downloads in the MySQL database, or write a customized script (accessible only by administrators) to retrieve the number of downloads.
[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan