etag php,php 超大文件下载程序[http 缓存协商,Etag标记,断点续传]

002 $file_path = './download/download_cn.rar';

003

004 //使用方法

005 downFile($file_path);

006

007 // 服务器文件路径,下载文件名字(默认为服务器文件名),是否许可用户下载方式(默认可选),速度限制(默认自动),文件类型(默认所有)

008 function downFile($fileName, $fancyName = '', $forceDownload = true, $speedLimit = 0, $contentType = '') {

009 if (!is_readable($fileName))

010 {

011 header("HTTP/1.1 404 Not Found");

012 return false;

013 }

014

015 $fileStat = stat($fileName);

016 $lastModified = $fileStat['mtime'];

017

018 $md5 = md5($fileStat['mtime'] .'='. $fileStat['ino'] .'='. $fileStat['size']);

019 $etag = '"' . $md5 . '-' . crc32($md5) . '"';

020

021 header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $lastModified) . ' GMT');

022 header("ETag: $etag");

023

024 if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified)

025 {

026 header("HTTP/1.1 304 Not Modified");

027 return true;

028 }

029

030 if (isset($_SERVER['HTTP_IF_UNMODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_UNMODIFIED_SINCE']) < $lastModified)

031 {

032 header("HTTP/1.1 304 Not Modified");

033 return true;

034 }

035

036 if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag)

037 {

038 header("HTTP/1.1 304 Not Modified");

039 return true;

040 }

041

042 if ($fancyName == '')

043 {

044 $fancyName = basename($fileName);

045 }

046

047 if ($contentType == '')

048 {

049 $contentType = 'application/octet-stream';

050 }

051

052 $fileSize = $fileStat['size'];

053

054 $contentLength = $fileSize;

055 $isPartial = false;

056

057 if (isset($_SERVER['HTTP_RANGE']))

058 {

059 if (preg_match('/^bytes=(d*)-(d*)$/', $_SERVER['HTTP_RANGE'], $matches))

060 {

061 $startPos = $matches[1];

062 $endPos = $matches[2];

063

064 if ($startPos == '' && $endPos == '')

065 {

066 return false;

067 }

068

069 if ($startPos == '')

070 {

071 $startPos = $fileSize - $endPos;

072 $endPos = $fileSize - 1;

073 }

074 else if ($endPos == '')

075 {

076 $endPos = $fileSize - 1;

077 }

078

079 $startPos = $startPos < 0 ? 0 : $startPos;

080 $endPos = $endPos > $fileSize - 1 ? $fileSize - 1 : $endPos;

081

082 $length = $endPos - $startPos + 1;

083

084 if ($length < 0)

085 {

086 return false;

087 }

088

089 $contentLength = $length;

090 $isPartial = true;

091 }

092 }

093

094 // send headers

095 if ($isPartial)

096 {

097 header('HTTP/1.1 206 Partial Content');

098 header("Content-Range: bytes $startPos-$endPos/$fileSize");

099

100 }

101 else

102 {

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

104 $startPos = 0;

105 $endPos = $contentLength - 1;

106 }

107

108 header('Pragma: cache');

109 header('Cache-Control: public, must-revalidate, max-age=0');

110 header('Accept-Ranges: bytes');

111 header('Content-type: ' . $contentType);

112 header('Content-Length: ' . $contentLength);

113

114 if ($forceDownload)

115 {

116 header('Content-Disposition: attachment; filename="' . rawurlencode($fancyName). '"');

117 }

118

119 header("Content-Transfer-Encoding: binary");

120

121 $bufferSize = 2048;

122

123 if ($speedLimit != 0)

124 {

125 $packetTime = floor($bufferSize * 1000000 / $speedLimit);

126 }

127

128 $bytesSent = 0;

129 $fp = fopen($fileName, "rb");

130 fseek($fp, $startPos);

131 while ($bytesSent < $contentLength && !feof($fp) && connection_status() == 0 )

132 {

133 if ($speedLimit != 0)

134 {

135 list($usec, $sec) = explode(" ", microtime());

136 $outputTimeStart = ((float)$usec + (float)$sec);

137 }

138

139 $readBufferSize = $contentLength - $bytesSent < $bufferSize ? $contentLength - $bytesSent : $bufferSize;

140 $buffer = fread($fp, $readBufferSize);

141

142 echo $buffer;

143

144 ob_flush();

145 flush();

146

147 $bytesSent += $readBufferSize;

148

149 if ($speedLimit != 0)

150 {

151 list($usec, $sec) = explode(" ", microtime());

152 $outputTimeEnd = ((float)$usec + (float)$sec);

153

154 $useTime = ((float) $outputTimeEnd - (float) $outputTimeStart) * 1000000;

155 $sleepTime = round($packetTime - $useTime);

156 if ($sleepTime > 0)

157 {

158 usleep($sleepTime);

159 }

160 }

161 }

162 return true;

163 }

164 ?>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值