ホームページ >バックエンド開発 >PHPチュートリアル >PHP大容量ファイルダウンロードプログラム[httpキャッシュネゴシエーション、Etagマーク、ブレークポイントレジューム]_PHPチュートリアル
002 $file_path = './download/download_cn.rar';
003
004 //
005 downFile($file_path) の使い方
006
007 // server ファイルパス、ダウンロードファイル名 (デフォルトはサーバーファイル名)、ユーザーにダウンロードを許可するかどうか (デフォルトはオプション)、速度制限 (デフォルトは自動)、ファイルタイプ (デフォルトはすべて)
008 function downFile($fileName, $fancyName = '', $forceDownload = true, $speedLimit = 0, $contentType = '') {
009 if (!is_readable($fileName))
010 {
011 header("HTTP/1.1 404 が見つかりません" ) ;
017
018 $md5 = md5 ($fileStat['mtime'] .'='.$fileStat['ino'] .'='.$fileStat['size']); $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($_S) ERVER['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 未変更" );
039 true を返す
040 }
041 if ($fancyName == '')
043 {
044 $fancyName = ベース名
045 }
046
047 if ($contentType == '')
048 { 53
054 $contentLength = $fileSize;
055 $isPartial = false
056
057 if (isset($_SERVER['HTTP_RANGE' ]))
058 {
059 if (preg_match('/^byte s=(d*)-(d* ;
063
064 if ($startPos == '' && $endPos == '' )
066 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
085 {
086 false を返します。
087 }
088
089 $contentLength = $length;
090 $isPartial = true;
091 }
092 }
093
094 // ヘッダーを送信
095 if ($isPartial)
096 {
097 header('HTTP/1.1 206 部分コンテンツ');
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: キャッシュ');
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 リスト( $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 flash();
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 trueを返します。
163 }
164 ?>