<? Php tutorial
002 $ file_path = './download/download_cn.rar ';
003
004 // usage
005 downFile ($ file_path );
006
007 // Server File Path, download file name (default: Server File name), permit user download method (optional by default), speed limit (automatically by default), file type (default: All)
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 maid ();
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?>