首页 > php框架 > php 超大文件下载类 支持2g以上文件 支持断点续传

php 超大文件下载类 支持2g以上文件 支持断点续传

<?php教程 

002 /** 

003  * <SPAN class=t_tag onclick=tagshow(event) href="tag.php?name=%CE%C4%BC%FE">文件</SPAN>传输,支持断点续传。 

004  * 2g以上超大文件也有效 

005  * @author MoXie 

006  */

007 class Transfer { 

008     /** 

009      * 缓冲单元 

010      */

011     const BUFF_SIZE = 5120; // 1024 * 5 

012     /** 

013      * 文件地址 

014      * @var <String> 

015      */

016     private $filePath; 

017     /** 

018      * 文件大小 

019      * @var <String> Php超大数字 <SPAN class=t_tag onclick=tagshow(event) href="tag.php?name=%D7%D6%B7%FB">字符</SPAN>串形式描述 

020      */

021     private $fileSize; 

022     /** 

023      * 文件类型 

024      * @var <String> 

025      */

026     private $mimeType; 

027     /** 

028      * 请求区域(范围) 

029      * @var <String> 

030      */

031     private $range; 

032     /** 

033      * 是否写入日志 

034      * @var <Boolean> 

035      */

036     private $isLog = false; 

037     /** 

038      * 

039      * @param <String> $filePath 文件路径 

040      * @param <String> $mimeType  文件类型 

041      * @param <String> $range 请求区域(范围) 

042      */

043     function __construct($filePath, $mimeType = null , $range = null) { 

044         $this->filePath = $filePath; 

045         $this->fileSize = sprintf(%u,filesize($filePath)); 

046         $this->mimeType = ($mimeType != null)?$mimeType:"application/octet-stream"; //  bin 

047         $this->range = trim($range); 

048     } 

049     /** 

050      *  获取文件区域 

051      * @return <Map> {start:long,end:long} or null 

052      */

053     private function getRange() { 

054         /** 

055          *  Range: bytes=-128 

056          *  Range: bytes=-128 

057          *  Range: bytes=28-175,382-399,510-541,644-744,977-980 

058          *  Range: bytes=28-175n380 

059          *  type 1 

060          *  RANGE: bytes=1000-9999 

061          *  RANGE: bytes=2000-9999 

062          *  type 2 

063          *  RANGE: bytes=1000-1999 

064          *  RANGE: bytes=2000-2999 

065          *  RANGE: bytes=3000-3999 

066          */

067         if (!empty($this->range)) { 

068             $range = preg_replace(/[s|,].*/,,$this->range); 

069             $range = explode(-,substr($range,6)); 

070             if (count($range) < 2 ) { 

071                 $range[1] = $this->fileSize; // Range: bytes=-100 

072             } 

073             $range = array_combine(array(start,end),$range); 

074             if (empty($range[start])) { 

075                 $range[start] = 0; 

076             } 

077             if (!isset ($range[end]) || empty($range[end])) { 

078                 $range[end] = $this->fileSize; 

079             } 

080             return $range; 

081         } 

082         return null; 

083     } 

084     /** 

085      * 向客户端发送文件 

086      */

087     public function send() { 

088         $fileHande = fopen($this->filePath, rb); 

089         if ($fileHande) { 

090             // setting 

091             ob_end_clean();// clean cache 

092             ob_start(); 

093             ini_set(output_buffering, Off); 

094             ini_set(zlib.output_compression, Off); 

095             $magicQuotes = get_magic_quotes_gpc(); 

096             set_magic_quotes_runtime(0); 

097             // init 

098             $lastModified = gmdate(D, d M Y H:i:s, filemtime($this->filePath)). GMT; 

099             $etag = sprintf(w/"%s:%s",md5($lastModified),$this->fileSize); 

100             $ranges = $this->getRange(); 

101             // headers 

102             header(sprintf(Last-Modified: %s,$lastModified)); 

103             header(sprintf(ETag: %s,$etag)); 

104             header(sprintf(Content-Type: %s,$this->mimeType)); 

105             $disposition = attachment; 

106             if (strpos($this->mimeType,image/) !== FALSE) { 

107                 $disposition = inline; 

108             } 

109             header(sprintf(Content-Disposition: %s; filename="%s",$disposition,basename($this->filePath))); 

110   

111             if ($ranges != null) { 

112                 if ($this->isLog) { 

113                     $this->log(json_encode($ranges). .$_SERVER[HTTP_RANGE]); 

114                 } 

115                 header(HTTP/1.1 206 Partial Content); 

116                 header(Accept-Ranges: bytes); 

117                 header(sprintf(Content-Length: %u,$ranges[end] - $ranges[start])); 

118                 header(sprintf(Content-Range: bytes %s-%s/%s, $ranges[start], $ranges[end],$this->fileSize)); 

119                 // 

120                 fseek($fileHande, sprintf(%u,$ranges[start])); 

121             }else { 

122                 header("HTTP/1.1 200 OK"); 

123                 header(sprintf(Content-Length: %s,$this->fileSize)); 

124             } 

125             // read file 

126             $lastSize = 0; 

127             while(!feof($fileHande) && !connection_aborted()) { 

128                 $lastSize = sprintf("%u", bcsub($this->fileSize,sprintf("%u",ftell($fileHande)))); 

129                 if (bccomp($lastSize,self::BUFF_SIZE) > 0) { 

130                     $lastSize = self::BUFF_SIZE; 

131                 } 

132                 echo fread($fileHande, $lastSize); 

133                 flush(); 

134                 ob_flush(); 

135             } 

136             set_magic_quotes_runtime($magicQuotes); 

137             ob_end_flush(); 

138         } 

139         if ($fileHande != null) { 

140             fclose($fileHande); 

141         } 

142     } 

143     /** 

144      * 设置记录 

145      * @param <Boolean> $isLog  是否记录 

146      */

147     public function setIsLog($isLog = true) { 

148         $this->isLog = $isLog; 

149     } 

150     /** 

151      * 记录 

152      * @param <String> $msg  记录信息 

153      */

154     private function log($msg) { 

155         try { 

156             $handle = fopen(transfer_log.txt, a); 

157             fwrite($handle, sprintf(%s : %s.<SPAN class=t_tag onclick=tagshow(event) href="tag.php?name=PHP">PHP</SPAN>_EOL,date(Y-m-d H:i:s),$msg)); 

158             fclose($handle); 

159         }catch(Exception $e) { 

160             // null; 

161         } 

162     } 

163 } 

164 date_default_timezone_set(Asia/Shanghai); 

165 error_reporting(E_STRICT); 

166 function errorHandler($errno, $errstr, $errfile, $errline) { 

167     echo <p>error:,$errstr,</p>; 

168     exit(); 

169 } 

170 set_error_handler(errorHandler); 

171 define(IS_DEBUG,true); 

172   

173 // 

174 // 

175 $filePath = /Movie/The.Hurt.Locker.2008.x264.AC3-WAF.mkv; 

176 $mimeType = audio/x-matroska; 

177 $range = isset($_SERVER[HTTP_RANGE])?$_SERVER[HTTP_RANGE]:null; 

178 if (IS_DEBUG) { 

179 //    $range = "bytes=1000-1999n2000"; 

180 //    $range = "bytes=1000-1999,2000";  

181 //    $range = "bytes=1000-1999,-2000";  

182 //    $range = "bytes=1000-1999,2000-2999";  

183 } 

184 set_time_limit(0); 

185 $transfer = new Transfer($filePath,$mimeType,$range); 

186 if (IS_DEBUG) { 

187     $transfer->setIsLog(true); 

188 } 

189 $transfer->send(); 

190 ?>


本文地址:http://www.phprm.com/frame/php1005013.html

转载随意,但请附上文章地址:-)

标签:none

发表留言