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 ?>