Would you like to be notified for every new articles? Please click HERE to subscribe for newsletter.

PHP Download Script

  • Posted on: 15 January 2011
  • By: admin

This is a PHP script that can be used to manage the download process. The advantages of using PHP script for handling the download process is we can prevent user to download the file directly, we can also limit the download speed to the desired speed, and we can also count how many times that file has been downloaded.

The script below has some features such as :

  • Configurable download speed.
  • Resumable download capability.

<?php
// If user click the download link
if(isset($_GET['filename'])){
        
// The directory of downloadable files
        // This directory should be unaccessible from web
        
$file_dir="/tmp/";

        

// Replace the slash and backslash character with empty string
        // The slash and backslash character can be dangerous
        
$file_name=str_replace("/"""$_GET['filename']);
        
$file_name=str_replace("\\"""$file_name);

        

// If the requested file is exist
        
if(file_exists($file_dir.$file_name)){
                
// Get the file size
                
$file_size=filesize($file_dir.$file_name);
                
// Open the file
                
$fh=fopen($file_dir.$file_name"r");

                

// Download speed in KB/s
                
$speed=5;

                

// Initialize the range of bytes to be transferred
                
$start=0;
                
$end=$file_size-1;

                

// Check HTTP_RANGE variable
                
if(isset($_SERVER['HTTP_RANGE']) &&
                        
preg_match('/^bytes=(\d+)-(\d*)/'$_SERVER['HTTP_RANGE'], $arr)){
                        
                        
// Starting byte
                        
$start=$arr[1];
                        if(
$arr[2]){
                                
// Ending byte
                                
$end=$arr[2];
                        }
                }

                

// Check if starting and ending byte is valid
                
if($start>$end || $start>=$file_size){
                        
header("HTTP/1.1 416 Requested Range Not Satisfiable");
                        
header("Content-Length: 0");
                }
                else{
                        
// For the first time download
                        
if($start==&& $end==$file_size){
                                
// Send HTTP OK header
                                
header("HTTP/1.1 200 OK");
                        }
                        else{
                                
// For resume download
                                // Send Partial Content header
                                
header("HTTP/1.1 206 Partial Content");
                                
// Send Content-Range header
                                
header("Content-Range: bytes ".$start."-".$end."/".$file_size);
                        }

                        

// Bytes left
                        
$left=$end-$start+1;

                        

// Send the other headers
                        
header("Content-Type: application/octet-stream");
                        
header("Accept-Ranges: bytes");
                        
// Content length should be the bytes left
                        
header("Content-Length: ".$left);
                        
header("Content-Disposition: attachment; filename=".$file_name);
                        
                        
// Read file from the given starting bytes
                        
fseek($fh$start);
                        
// Loop while there are bytes left
                        
while($left>0){
                                
// Bytes to be transferred
                                // according to the defined speed
                                
$bytes=$speed*1024;
                                
// Read file per size
                                
echo fread($fh$bytes);
                                
// Flush the content to client
                                
flush();
                                
// Substract bytes left with the tranferred bytes
                                
$left-=$bytes;
                                
// Delay for 1 second
                                
sleep(1);
                        }
                }

                

fclose($fh);
        }
        else{
                
// If the requested file is not exist
                // Display error message
                
echo "File not found!";
        }
        
        exit();
}
?>
<html>
<head>
        <title>Home</title>
</head>
<body>
        <a href="index.php?filename=file.pdf">Download</a>
</body>
</html>
?>
Tags: 

Comments

How to use this? Give a tutorial pls

It's easy to use it. You just need to put your files into a directory. The directory can be changed from the $file_dir variable. And then in your HTML you just need to create link that point to this script and pass the filename as your query string, eg. yourscript.php?filename=yourfilename.pdf.

Really nice script, and it seems like it will be very easy to integrate with a database of files. Thanks

i user this script in my main site (example www.main.com) , but my files uploaded in host dl (example www.dl.main.com) . when i put my files from dl.main.com into directory . it gives an error . please tell me how can i fix this problem . thanks a lot

I got it to work on my localhost wamp server, but I cant get it to work on my webserver using Cpanel. whatever I do it can't find the file: file not found. The path is right, I can pull up the file in the search bar. Any suggestions?

I added this echo snippet:
// Replace the slash and backslash character with empty string
// The slash and backslash character can be dangerous
$file_name=str_replace("/", "", $_GET['filename']);
$file_name=str_replace("\\", "", $file_name);
echo ($file_dir.$file_name);
And when I run the file, I get the path and file, copy and paste it into the browser, and it opens up the file. So I know I have the path right. Could it be a permission problem?

Ok I figured it out. The path was wrong, I need to learn about paths! I was trying to use:
www.mysite.com/file_folder (which works if I type it in the browser manually)
The correct path was:
/home/******/public_html/file_folder/

As a sidenote, adding the echo snippet caused another problem, "Warning: Cannot modify header information - headers already sent by...". I deleted the echo and it worked great.

Thanks for the script!!

its too good..
thank u very much..

Thanks for this handy script! I'm using it for images: http://bossanova.im/en/photography/wallpapers/index.html

Will this script prevent Google from indexing my images? I actually want Google to index them, so that they show up in Google Image searches.

Great script;
Thank you so much.

In which way i must edit your script to remove the download speed limit ? I got an other script running which handles that, so i don't need a second one.

Thanks !

if($start==0 && $end==$file_size){

should be

if( !$start && $end==$file_size - 1){

Thank you for this neat scrip.

How do i can implement this on WordPress site?

Bundles of Thanxxxxxxxxxxxxxxxxxxxxxxxxxxx okaaaaaaaaaa g

Good script, but when I try to download file...there is a error:
Cannot modify header information - headers already sent ...

How to repair that - I already repaired File not found error by removing first / in file_dir ...

Thx VentyCZ

Good script, but when I try to download file...there is a error:
Cannot modify header information - headers already sent ...

How to repair that - I already repaired File not found error by removing first / in file_dir ...

Thx VentyCZ

this script is good. good work

GJHGJHJKHJKHKJH

I was looking such a script. I''v found this one, works great in FF IE and Chrome but not in Opera.
Opera doesn''t start the download, but the script works fine in the other browsers. Great work thanks.

Version 12.15
Buils 1748
Platform Win32
Systeem Windows 7
Browseridentificatie Opera/9.80 (Windows NT 6.1) Presto/2.12.388 Version/12.15

Thank you for this script. Simple and useful.

Hi, thanks you code,

I think this code only work if file on our server but if we want to download file from other server or site then this code not work.

I have a problem in this script, when I pause to download (IDM) and then start it start download from zero byte even I downloaded some bytes before pause.
What is the problem? can you fix this??

This PHP download script has many features like the increased configurable speed and resumable download capability is also very high in this. The click information of the article proved very much helpful for me as this is very easy to use.

Add new comment

Limited HTML

  • Allowed HTML tags: <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.