Php large file download class supports more than 2 GB files support resumable data transfer

Source: Internet
Author: User
Tags php tutorial ranges sprintf

<? Php Tutorial

002 /**

003 * <SPAN class = t_tag onclick = tagshow (event) href = "tag. php? Name = % CE % C4 % BC % FE "> File </SPAN> Transmission. Resumable data transfer is supported.

004*2 GB or more ultra-large files 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 <String>

015 */

016 private $ filePath;

017 /**

018 * file size

019 * @ var <String> Php oversized number <SPAN class = t_tag onclick = tagshow (event) href = "tag. php? Name = % D7 % D6 % B7 % FB "> Character </SPAN> string description

020 */

021 private $ fileSize;

022 /**

023 * file type

024 * @ var <String>

025 */

026 private $ mimeType;

027 /**

028 * Request region (range)

029 * @ var <String>

030 */

031 private $ range;

032 /**

033 * whether to write logs

034 * @ var <Boolean>

035 */

036 private $ isLog = false;

037 /**

038 *

039 * @ param <String> $ filePath file path

040 * @ param <String> $ mimeType file type

041 * @ param <String> $ range request region (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 * obtain the file region

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 * send a file to the 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 maid ();

135}

136 set_magic_quotes_runtime ($ magicQuotes );

137 ob_end_flush ();

138}

139 if ($ fileHande! = Null ){

140 fclose ($ fileHande );

141}

142}

143 /**

144 * Set Records

145 * @ param <Boolean> $ whether isLog is recorded

146 */

147 public function setIsLog ($ isLog = true ){

148 $ this-> isLog = $ isLog;

149}

150 /**

151 * Records

152 * @ param <String> $ msg record information

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/vie ';

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 ";

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

182 // $ range = "bytes = 1000-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?>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.