有些文件或数据的下载需要收到保护,会用动态语言控制下载的权限控制。下面是早期学习HTTP协议时写的一个PHP下载文件支持断点续传的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<?php
/**
* 作者 于恩水<yuenshui@126.com>
* 支持断点续传下载
* 实例代码:
* $down = new SD_DownLoad();
* $down->Down('E:/iso/MS.Office2003SP1.CHS.iso');
**/
class SD_DownLoad {
/**
* 下载的开始点
*
* @access private
* @var integer
*/
private $mDownStart;
/**
* 文件大小
*
* @access private
* @var integer
*/
private $mFileSize;
/**
* 文件句柄
*
* @access private
* @var integer
*/
private $mFileHandle;
/**
* 文件全路径
*
* @access private
* @var string
*/
private $mFilePath;
/**
* 文件下载时显示的文件名
*
* @access private
* @var string
*/
private $mFileName;
/**
* 构造函数
*
* @access public
* @return void
**/
public function __construct() {
}
/**
* 下载
*
* @param string $pFilePath 文件全路径
* @param string pFileName 文件下载时显示的文件名,缺省为实际文件名
* @access public
* @return void
**/
public function Down($pFilePath, $pFileName = '') {
$this->mFilePath = $pFilePath;
if(!$this->IniFile()) $this->SendError();
$this->mFileName = empty($pFileName) ? $this->GetFileName() : $pFileName;
$this->IniFile();
$this->SetStart();
$this->SetHeader();
$this->Send();
}
/**
* 初始化文件信息
*
* @access private
* @return boolean
**/
private function IniFile() {
if(!is_file($this->mFilePath)) return false;
$this->mFileHandle = fopen($this->mFilePath, 'rb');
$this->mFileSize = filesize($this->mFilePath);
return true;
}
/**
* 设置下载开始点
*
* @access private
* @return void
**/
private function SetStart() {
if (!empty($_SERVER['HTTP_RANGE']) && preg_match("/^bytes=([d]?)-([d]?)$/i", $_SERVER['HTTP_RANGE'], $match)) {
if(empty($match[1])) $this->mDownStart = $match[1];
fseek($this->mFileHandle, $this->mDownStart);
}
else {
$this->mDownStart = 0;
}
}
/**
* 设置http头
*
* @access private
* @return void
**/
private function SetHeader() {
@header("Cache-control: public");
@header("Pragma: public");
Header("Content-Length: " . ($this->mFileSize - $this->mDownStart));
if ($this->mDownStart > 0) {
@Header("HTTP/1.1 206 Partial Content");
Header("Content-Ranges: bytes" . $this->mDownStart . "-" . ($this->mFileSize - 1) . "/" . $this->mFileSize);
}
else {
Header("Accept-Ranges: bytes");
}
@header("Content-Type: application/octet-stream");
@header("Content-Disposition: attachment;filename=" . $this->mFileName);
}
/**
* 获取全路径里的文件名部分
*
* @access private
* @return string
**/
private function GetFileName() {
return basename ($this->mFilePath);
}
/**
* 发送数据
*
* @access private
* @return void
**/
private function Send() {
fpassthru($this->mFileHandle);
}
/**
* 发送错误
*
* @access public
* @return void
**/
public function SendError() {
@header("HTTP/1.0 404 Not Found");
@header("Status: 404 Not Found");
exit();
}
}
?>

注意:本站博文均系原创,欢迎转载,请注明出处和原网址