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