Home  >  Article  >  Backend Development  >  PHP super large file download class supports files above 2g and supports breakpoint resume_PHP tutorial

PHP super large file download class supports files above 2g and supports breakpoint resume_PHP tutorial

WBOY
WBOYOriginal
2016-07-20 11:07:241336browse

002 /**

003 * File transmission, supports interruption Click resume.

004 * Very large files above 2g are also valid

005 * @author MoXie

006*/

007 class Transfer { 

008     /**

009 * Buffer unit

010*/

011     const BUFF_SIZE = 5120; // 1024 * 5 

012     /**

013 * File address

014 * @var

015*/

016     private $filePath; 

017     /**

018 * File size

019 * @var Php large numberCharacterString form description

020*/

021     private $fileSize; 

022     /**

023 * File type

024 * @var

025*/

026     private $mimeType; 

027     /**

028 * Request area (range)

029 * @var

030*/

031     private $range; 

032     /**

033 * Whether to write to the log

034 * @var

035*/

036     private $isLog = false; 

037     /**

038 *

039 * @param $filePath file path

040 * @param $mimeType file type

041 * @param $range request area (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 * Get file area

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 * Send file to client

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 * Set record

145 * @param $isLog Whether to record

146*/

147     public function setIsLog($isLog = true) { 

148         $this->isLog = $isLog; 

149     } 

150     /**

151 * Record

152 * @param $msg Record information

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


www.bkjia.comtruehttp://www.bkjia.com/PHPjc/444968.htmlTechArticle?php教程 002 /** 003 * SPAN class=t_tag onclick=tagshow(event) href=tag.php?name=%CE%C4%BC%FE文件/SPAN传输,支持断点续传。 004 * 2g以上超大文件也有效 005 * @...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn