Login   Register  
PHP Classes
elePHPant
Icontem

File: class.Bf_Download.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Mourad Boufarguine  >  Bf_Download  >  class.Bf_Download.php  >  Download  
File: class.Bf_Download.php
Role: Class source
Content type: text/plain
Description: The class file
Class: Bf_Download
Serve files for download with resume support
Author: By
Last change: Fix a bug when fopen returns an invalid stream resource resulting in an infinite loop (Thanks to Brian Clark)
Date: 4 years ago
Size: 8,152 bytes
 

Contents

Class file image Download
<?php

/**********************************************************************
**
** A class to download files
** Version 1.0
** Features : 
**      - hide the real path to the file
**      - allow / disallow download resuming
**      - partial download (useful for download managers)
**      - rename the file on the fly
**      - limit download speed
**
** Author: Mourad Boufarguine / EPT <mourad.boufarguine@gmail.com>
**
** License: Public Domain
** Warranty: None
**
***********************************************************************/

class Bf_Download{
    
    
// just one array to gather all the properties of a download
    
private $properties = array("path" => "",       // the real path to the file 
                                
"name" => "",       // to rename the file on the fly
                                
"extension" => "",  // extension of the file
                                
"type" => "",       // the type of the file
                                
"size" => "",       // the file size
                                
"resume" => "",     // allow / disallow resuming
                                
"max_speed" => ""   // speed limit (ko) ( 0 = no limit)
                                
);          

    
// the constructor
    
public function __construct($path$name=""$resume="off"$max_speed=0){  // by default, resuming is NOT allowed and there is no speed limit
        
$name = ($name == "") ? substr(strrchr("/".$path,"/"),1) : $name// if "name" is not specified, th file won't be renamed
        
$file_extension strtolower(substr(strrchr($path,"."),1));       // the file extension
        
switch( $file_extension ) {                                       // the file type
            
case "mp3"$content_type="audio/mpeg"; break;
            case 
"mpg"$content_type="video/mpeg"; break;
            case 
"avi"$content_type="video/x-msvideo"; break;
            case 
"wmv"$content_type="video/x-ms-wmv";break;
            case 
"wma"$content_type="audio/x-ms-wma";break; 
            default: 
$content_type="application/force-download";
        }
        
$file_size filesize($path);                                     // the file size
        
$this->properties =  array(
                                    
"path" => $path
                                    
"name" => $name
                                    
"extension" =>$file_extension,
                                    
"type"=>$content_type
                                    
"size" => $file_size
                                    
"resume" => $resume
                                    
"max_speed" => $max_speed
                                    
);
    }
    
    
// public function to get the value of a property
    
public function get_property ($property){
        if ( 
array_key_exists($property,$this->properties) )   // check if the property do exist
            
return $this->properties[$property];               // get its value
        
else
            return 
null;                                       // else return null
    
}
    
    
// public function to set the value of a property        
    
public function set_property ($property$value){
        if ( 
array_key_exists($property$this->properties) ){ // check if the property do exist
            
$this->properties[$property] = $value;             // set the new value
            
return true;
        } else
            return 
false;
    }
    
    
// public function to start the download
    
public function download_file(){
        if ( 
$this->properties['path'] == "" )                 // if the path is unset, then error !
            
echo "Nothing to download!";
        else {
            
// if resuming is allowed ...
            
if ($this->properties["resume"] == "on") {
                if(isset(
$_SERVER['HTTP_RANGE'])) {            // check if http_range is sent by browser (or download manager)
                    
list($a$range)=explode("=",$_SERVER['HTTP_RANGE']);  
                    
ereg("([0-9]+)-([0-9]*)/?([0-9]*)",$range,$range_parts); // parsing Range header
                    
$byte_from $range_parts [1];     // the download range : from $byte_from ...
                    
$byte_to $range_parts [2];       // ... to $byte_to 
                
} else
                    if(isset(
$_ENV['HTTP_RANGE'])) {       // some web servers do use the $_ENV['HTTP_RANGE'] instead
                        
list($a$range)=explode("=",$_ENV['HTTP_RANGE']);
                        
ereg("([0-9]+)-([0-9]*)/?([0-9]*)",$range,$range_parts); // parsing Range header
                        
$byte_from $range_parts [1];     // the download range : from $byte_from ...
                        
$byte_to $range_parts [2];       // ... to $byte_to 
                    
}else{
                        
$byte_from 0;                         // if no range header is found, download the whole file from byte 0 ...
                        
$byte_to $this->properties["size"] - 1;   // ... to the last byte
                    
}
                if (
$byte_to == "")                             // if the end byte is not specified, ...
                    
$byte_to $this->properties["size"] -1;    // ... set it to the last byte of the file
                
header("HTTP/1.1 206 Patial Content");          // send the partial content header
            // ... else, download the whole file
            
} else {
                
$byte_from 0;
                
$byte_to $this->properties["size"] - 1;
            }
            
            
$download_range $byte_from."-".$byte_to."/".$this->properties["size"]; // the download range
            
$download_size $byte_to $byte_from;                                  // the download length
            
            // download speed limitation
            
if (($speed $this->properties["max_speed"]) > 0)                       // determine the max speed allowed ...
                
$sleep_time = ($speed) * 1e6;                                    // ... if "max_speed" = 0 then no limit (default)
            
else
                
$sleep_time 0;
            
            
// send the headers    
            
header("Pragma: public");                                                // purge the browser cache
            
header("Expires: 0");                                                    // ...
            
header("Cache-Control:");                                                // ...
            
header("Cache-Control: public");                                         // ... 
            
header("Content-Description: File Transfer");                            //  
            
header("Content-Type: ".$this->properties["type"]);                     // file type
            
header('Content-Disposition: attachment; filename="'.$this->properties["name"].'";');
            
header("Content-Transfer-Encoding: binary");                             // transfer method
            
header("Content-Range: $download_range");                                // download range
            
header("Content-Length: $download_size");                                // download length
            
            // send the file content        
            
$fp=fopen($this->properties["path"],"r");       // open the file 
            
if(!fp) exit; // if $fp is not a valid stream resource, exit
            
fseek($fp,$byte_from);                          // seek to start of missing part   
            
while(!feof($fp)){                              // start buffered download  
                
set_time_limit(0);                           // reset time limit for big files (has no effect if php is executed in safe mode)
                
print(fread($fp,1024*8));                   // send 8ko 
                
flush();
                
usleep($sleep_time);                        // sleep (for speed limitation)
            
}
            
fclose($fp);                                    // close the file
            
exit;  
        }
    }
}
?>