php大文件下载支持断点续传

  1 <?php  
  2 /** php下载类,支持断点续传 
  3 * 
  4 *   Func: 
  5 *   download: 下载文件 
  6 *   setSpeed: 设置下载速度 
  7 *   getRange: 获取header中Range 
  8 */  
  9 class FileDownload{ // class start  
 10     private $_speed = 512;   // 下载速度  
 11 
 12     /** 下载 
 13     * @param String  $file   要下载的文件路径 
 14     * @param String  $name   文件名称,为空则与下载的文件名称一样 
 15     * @param boolean $reload 是否开启断点续传 
 16     */  
 17     public function download($file, $name='', $reload=false){  
 18         if(file_exists($file)){  
 19             if($name==''){  
 20                 $name = basename($file);  
 21             }  
 22 
 23             $fp = fopen($file, 'rb');  
 24             $file_size = filesize($file);  
 25             
 26             $ranges = $this->getRange($file_size);  
 27 
 28             header('cache-control:public');  
 29             header('content-type:application/octet-stream');  
 30             header('content-disposition:attachment; filename='.$name);  
 31 
 32 
 33             if($reload && $ranges!=null){ // 使用续传  
 34                 header('HTTP/1.1 206 Partial Content');  
 35                 header('Accept-Ranges:bytes');  
 36                 // 剩余长度  
 37                 header(sprintf('content-length:%u',$ranges['end']-$ranges['start']));  
 38                 // range信息  
 39                 header(sprintf('content-range:bytes %s-%s/%s', $ranges['start'], $ranges['end'], $file_size));  
 40                 // fp指针跳到断点位置  
 41                 fseek($fp, sprintf('%u', $ranges['start']));  
 42             }else{  
 43                 header('HTTP/1.1 200 OK');  
 44                 header('content-length:'.$file_size);  
 45             }  
 46 
 47             while(!feof($fp)){  
 48                 echo fread($fp, round($this->_speed*1024,0));  
 49                 ob_flush();  
 50                 sleep(1); // 用于测试,减慢下载速度  
 51             }  
 52             ($fp!=null) && fclose($fp);  
 53         }else{  
 54             return '';  
 55         }  
 56     }  
 57 
 58     /** 设置下载速度 
 59     * @param int $speed 
 60     */  
 61 
 62     public function setSpeed($speed){  
 63         if(is_numeric($speed) && $speed>16 && $speed<4096){  
 64             $this->_speed = $speed;  
 65         }  
 66     }  
 67 
 68   
 69 
 70   
 71 
 72     /** 获取header range信息 
 73     * @param  int   $file_size 文件大小 
 74     * @return Array 
 75     */  
 76 
 77     private function getRange($file_size){  
 78         if(isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])){  
 79             $range = $_SERVER['HTTP_RANGE'];  
 80             $range = preg_replace('/[\s|,].*/', '', $range);  
 81             $range = explode('-', substr($range, 6));  
 82             if(count($range)<2){  
 83                 $range[1] = $file_size;  
 84             }  
 85             $range = array_combine(array('start','end'), $range);  
 86             if(empty($range['start'])){  
 87                 $range['start'] = 0;  
 88             }  
 89             if(empty($range['end'])){  
 90                 $range['end'] = $file_size;  
 91             }  
 92             return $range;  
 93         }  
 94         return null;  
 95     }  
 96 }
 97 
 98 
 99 $file = 'book.zip';  
100 $name = time().'.zip';  
101 $obj = new FileDownload();  
102 $flag = $obj->download($file, $name);  
103 //$flag = $obj->download($file, $name, true); // 断点续传  
104 
105 if(!$flag){  
106     echo 'file not exists';  
107 }  
108 
109 ?>

猜你喜欢

转载自www.cnblogs.com/saonian/p/9174293.html