【www.gdgbn.com--网页编辑器下载】

php教程 

002 /** 

003  * 文件传输,支持断点续传。 

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

005  * @author MoXie 

006  */

007 class Transfer { 

008     /** 

009      * 缓冲单元 

010      */

011     const BUFF_SIZE = 5120; // 1024 * 5 

012     /** 

013      * 文件地址 

014      * @var  

015      */

016     private $filePath; 

017     /** 

018      * 文件大小 

019      * @var Php超大数字 字符串形式描述 

020      */

021     private $fileSize; 

022     /** 

023      * 文件类型 

024      * @var  

025      */

026     private $mimeType; 

027     /** 

028      * 请求区域(范围) 

029      * @var  

030      */

031     private $range; 

032     /** 

033      * 是否写入日志 

034      * @var  

035      */

036     private $isLog = false; 

037     /** 

038      * 

039      * @param $filePath 文件路径 

040      * @param $mimeType  文件类型 

041      * @param $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 {"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 $isLog  是否记录 

146      */

147     public function setIsLog($isLog = true) { 

148         $this->isLog = $isLog; 

149     } 

150     /** 

151      * 记录 

152      * @param $msg  记录信息 

153      */

154     private function log($msg) { 

155         try { 

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

157             fwrite($handle, sprintf("%s : %s".PHP_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 "

error:",$errstr,"

"; 

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.gdgbn.com/shipin/24082/