本文共 6155 字,大约阅读时间需要 20 分钟。
PHP 下载远程文件类,支持断点续传下载,代码内含有具体的调用说明。程序主要是使用 HTTP 协议下载文件,HTTP1.1协议必须指定文档结束后关闭链接,否则读取文档时无法使用feof判断结束,可以有两种使用方法,具体请下载查看源码。 001 | <?php |
002 | /** |
003 | * 下载远程文件类支持断点续传 |
004 | */ |
005 | class HttpDownload { |
006 | private $m_url = "" ; |
007 | private $m_urlpath = "" ; |
008 | private $m_scheme = "http" ; |
009 | private $m_host = "" ; |
010 | private $m_port = "80" ; |
011 | private $m_user = "" ; |
012 | private $m_pass = "" ; |
013 | private $m_path = "/" ; |
014 | private $m_query = "" ; |
015 | private $m_fp = "" ; |
016 | private $m_error = "" ; |
017 | private $m_httphead = "" ; |
018 | private $m_html = "" ; |
019 | |
020 | /** |
021 | * 初始化 |
022 | */ |
023 | public function PrivateInit( $url ){ |
024 | $urls = "" ; |
025 | $urls = @ parse_url ( $url ); |
026 | $this ->m_url = $url ; |
027 | if ( is_array ( $urls )) { |
028 | $this ->m_host = $urls [ "host" ]; |
029 | if (! empty ( $urls [ "scheme" ])) $this ->m_scheme = $urls [ "scheme" ]; |
030 | if (! empty ( $urls [ "user" ])) $this ->m_user = $urls [ "user" ]; |
031 | if (! empty ( $urls [ "pass" ])) $this ->m_pass = $urls [ "pass" ]; |
032 | if (! empty ( $urls [ "port" ])) $this ->m_port = $urls [ "port" ]; |
033 | if (! empty ( $urls [ "path" ])) $this ->m_path = $urls [ "path" ]; |
034 | $this ->m_urlpath = $this ->m_path; |
035 | if (! empty ( $urls [ "query" ])) { |
036 | $this ->m_query = $urls [ "query" ]; |
037 | $this ->m_urlpath .= "?" . $this ->m_query; |
038 | } |
039 | } |
040 | } |
041 | |
042 | /** |
043 | * 打开指定网址 |
044 | */ |
045 | function OpenUrl( $url ) { |
046 | #重设各参数 |
047 | $this ->m_url = "" ; |
048 | $this ->m_urlpath = "" ; |
049 | $this ->m_scheme = "http" ; |
050 | $this ->m_host = "" ; |
051 | $this ->m_port = "80" ; |
052 | $this ->m_user = "" ; |
053 | $this ->m_pass = "" ; |
054 | $this ->m_path = "/" ; |
055 | $this ->m_query = "" ; |
056 | $this ->m_error = "" ; |
057 | $this ->m_httphead = "" ; |
058 | $this ->m_html = "" ; |
059 | $this ->Close(); |
060 | #初始化系统 |
061 | $this ->PrivateInit( $url ); |
062 | $this ->PrivateStartSession(); |
063 | } |
064 |
065 | /** |
066 | * 获得某操作错误的原因 |
067 | */ |
068 | public function printError() { |
069 | echo "错误信息:" . $this ->m_error; |
070 | echo "具体返回头:<br>" ; |
071 | foreach ( $this ->m_httphead as $k => $v ) { |
072 | echo "$k => $v <br>\r\n" ; |
073 | } |
074 | } |
075 | |
076 | /** |
077 | * 判别用Get方法发送的头的应答结果是否正确 |
078 | */ |
079 | public function IsGetOK() { |
080 | if ( ereg ( "^2" , $this ->GetHead( "http-state" )) ) { |
081 | return true; |
082 | } else { |
083 | $this ->m_error .= $this ->GetHead( "http-state" ). " - " . $this ->GetHead( "http-describe" ). "<br>" ; |
084 | return false; |
085 | } |
086 | } |
087 | |
088 | /** |
089 | * 看看返回的网页是否是text类型 |
090 | */ |
091 | public function IsText() { |
092 | if ( ereg ( "^2" , $this ->GetHead( "http-state" )) && eregi ( "^text" , $this ->GetHead( "content-type" ))) { |
093 | return true; |
094 | } else { |
095 | $this ->m_error .= "内容为非文本类型<br>" ; |
096 | return false; |
097 | } |
098 | } |
099 | /** |
100 | * 判断返回的网页是否是特定的类型 |
101 | */ |
102 | public function IsContentType( $ctype ) { |
103 | if ( ereg ( "^2" , $this ->GetHead( "http-state" )) && $this ->GetHead( "content-type" ) == strtolower ( $ctype )) { |
104 | return true; |
105 | } else { |
106 | $this ->m_error .= "类型不对 " . $this ->GetHead( "content-type" ). "<br>" ; |
107 | return false; |
108 | } |
109 | } |
110 | |
111 | /** |
112 | * 用 HTTP 协议下载文件 |
113 | */ |
114 | public function SaveToBin( $savefilename ) { |
115 | if (! $this ->IsGetOK()) return false; |
116 | if (@ feof ( $this ->m_fp)) { |
117 | $this ->m_error = "连接已经关闭!" ; |
118 | return false; |
119 | } |
120 | $fp = fopen ( $savefilename , "w" ) or die ( "写入文件 $savefilename 失败!" ); |
121 | while (! feof ( $this ->m_fp)) { |
122 | @fwrite( $fp , fgets ( $this ->m_fp,256)); |
123 | } |
124 | @fclose( $this ->m_fp); |
125 | return true; |
126 | } |
127 | |
128 | /** |
129 | * 保存网页内容为 Text 文件 |
130 | */ |
131 | public function SaveToText( $savefilename ) { |
132 | if ( $this ->IsText()) { |
133 | $this ->SaveBinFile( $savefilename ); |
134 | } else { |
135 | return "" ; |
136 | } |
137 | } |
138 | |
139 | /** |
140 | * 用 HTTP 协议获得一个网页的内容 |
141 | */ |
142 | public function GetHtml() { |
143 | if (! $this ->IsText()) return "" ; |
144 | if ( $this ->m_html!= "" ) return $this ->m_html; |
145 | if (! $this ->m_fp||@ feof ( $this ->m_fp)) return "" ; |
146 | while (! feof ( $this ->m_fp)) { |
147 | $this ->m_html .= fgets ( $this ->m_fp,256); |
148 | } |
149 | @fclose( $this ->m_fp); |
150 | return $this ->m_html; |
151 | } |
152 | |
153 | /** |
154 | * 开始 HTTP 会话 |
155 | */ |
156 | public function PrivateStartSession() { |
157 | if (! $this ->PrivateOpenHost()) { |
158 | $this ->m_error .= "打开远程主机出错!" ; |
159 | return false; |
160 | } |
161 | if ( $this ->GetHead( "http-edition" )== "HTTP/1.1" ) { |
162 | $httpv = "HTTP/1.1" ; |
163 | } else { |
164 | $httpv = "HTTP/1.0" ; |
165 | } |
166 | fputs ( $this ->m_fp, "GET " . $this ->m_urlpath. " $httpv\r\n" ); |
167 | fputs ( $this ->m_fp, "Host: " . $this ->m_host. "\r\n" ); |
168 | fputs ( $this ->m_fp, "Accept: */*\r\n" ); |
169 | fputs ( $this ->m_fp, "User-Agent: Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.2)\r\n" ); |
170 | #HTTP1.1协议必须指定文档结束后关闭链接,否则读取文档时无法使用 feof 判断结束 |
171 | if ( $httpv == "HTTP/1.1" ) { |
172 | fputs ( $this ->m_fp, "Connection: Close\r\n\r\n" ); |
173 | } else { |
174 | fputs ( $this ->m_fp, "\r\n" ); |
175 | } |
176 | $httpstas = fgets ( $this ->m_fp,256); |
177 | $httpstas = split( " " , $httpstas ); |
178 | $this ->m_httphead[ "http-edition" ] = trim( $httpstas [0]); |
179 | $this ->m_httphead[ "http-state" ] = trim( $httpstas [1]); |
180 | $this ->m_httphead[ "http-describe" ] = "" ; |
181 | for ( $i =2; $i < count ( $httpstas ); $i ++) { |
182 | $this ->m_httphead[ "http-describe" ] .= " " .trim( $httpstas [ $i ]); |
183 | } |
184 | while (! feof ( $this ->m_fp)) { |
185 | $line = str_replace ( "\"" , "" ,trim( fgets ( $this ->m_fp,256))); |
186 | if ( $line == "" ) break ; |
187 | if ( ereg ( ":" , $line )) { |
188 | $lines = split( ":" , $line ); |
189 | $this ->m_httphead[ strtolower (trim( $lines [0]))] = trim( $lines [1]); |
190 | } |
191 | } |
192 | } |
193 | |
194 | /** |
195 | * 获得一个Http头的值 |
196 | */ |
197 | public function GetHead( $headname ) { |
198 | $headname = strtolower ( $headname ); |
199 | if (isset( $this ->m_httphead[ $headname ])) { |
200 | return $this ->m_httphead[ $headname ]; |
201 | } else { |
202 | return "" ; |
203 | } |
204 | } |
205 | |
206 | /** |
207 | * 打开连接 |
208 | */ |
209 | public function PrivateOpenHost() { |
210 | if ( $this ->m_host== "" ) return false; |
211 | $this ->m_fp = @ fsockopen ( $this ->m_host, $this ->m_port, & $errno , & $errstr ,10); |
212 | if (! $this ->m_fp){ |
213 | $this ->m_error = $errstr ; |
214 | return false; |
215 | } else { |
216 | return true; |
217 | } |
218 | } |
219 | |
220 | /** |
221 | * 关闭连接 |
222 | */ |
223 | public function Close(){ |
224 | @fclose( $this ->m_fp); |
225 | } |
226 | } |
227 |
228 | #两种使用方法,分别如下: |
229 |
230 | #打开网页 |
231 | $httpdown = new HttpDownload(); |
232 | $httpdown ->OpenUrl( "http://www.google.com.hk" ); |
233 | echo $httpdown ->GetHtml(); |
234 | $httpdown ->Close(); |
235 |
236 |
237 | #下载文件 |
238 | $file = new HttpDownload(); # 实例化类 |
239 | $file ->OpenUrl( "http://www.ti.com.cn/cn/lit/an/rust020/rust020.pdf" ); # 远程文件地址 |
240 | $file ->SaveToBin( "rust020.pdf" ); # 保存路径及文件名 |
241 | $file ->Close(); # 释放资源 |
242 | ?> |
转载地址:http://emhvi.baihongyu.com/