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