分享一个超好用的php header下载函数
这篇文章主要为大家分享一个超好用的php header下载函数,需要的朋友可以参考下
<?php /** * 发送文件 * * @author: legend([email protected]) * @link: http://www.ugia.cn/?p=109 * @description: send file to client * @version: 1.0 * * @param string $fileName 文件名称或路径 * @param string $fancyName 自定义的文件名,为空则使用filename * @param boolean $forceDownload 是否强制下载 * @param integer $speedLimit 速度限制,单位为字节,0为不限制,不支持windows服务器 * @param string $$contentType 文件类型,默认为application/octet-stream * * @return boolean */ function sendFile($fileName, $fancyName = '', $forceDownload = true, $speedLimit = 0, $contentType = '') { if (!is_readable($fileName)) { header("HTTP/1.1 404 Not Found"); return false; }$fileStat = stat($fileName); $lastModified = $fileStat['mtime']; $md5 = md5($fileStat['mtime'] .'='. $fileStat['ino'] .'='. $fileStat['size']); $etag = '"' . $md5 . '-' . crc32($md5) . '"';
header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $lastModified) . ' GMT'); header("ETag: $etag"); if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified) { header("HTTP/1.1 304 Not Modified"); return true; }
if (isset($_SERVER['HTTP_IF_UNMODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_UNMODIFIED_SINCE']) < $lastModified) { header("HTTP/1.1 304 Not Modified"); return true; }
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag) { header("HTTP/1.1 304 Not Modified"); return true; }
if ($fancyName == '') { $fancyName = basename($fileName); } if ($contentType == '') { $contentType = 'application/octet-stream'; }
$fileSize = $fileStat['size']; $contentLength = $fileSize; $isPartial = false;
if (isset($_SERVER['HTTP_RANGE'])) { if (preg_match('/^bytes=(d*)-(d*)$/', $_SERVER['HTTP_RANGE'], $matches)) { $startPos = $matches[1]; $endPos = $matches[2];
if ($startPos == '' && $endPos == '') { return false; } if ($startPos == '') { $startPos = $fileSize - $endPos; $endPos = $fileSize - 1; } else if ($endPos == '') { $endPos = $fileSize - 1; }
$startPos = $startPos < 0 ? 0 : $startPos; $endPos = $endPos > $fileSize - 1 ? $fileSize - 1 : $endPos;
$length = $endPos - $startPos + 1;
if ($length < 0) { return false; }
$contentLength = $length; $isPartial = true; } } // send headers if ($isPartial) { header('HTTP/1.1 206 Partial Content'); header("Content-Range: bytes $startPos-$endPos/$fileSize"); } else { header("HTTP/1.1 200 OK"); $startPos = 0; $endPos = $contentLength - 1; }
header('Pragma: cache'); header('Cache-Control: public, must-revalidate, max-age=0'); header('Accept-Ranges: bytes'); header('Content-type: ' . $contentType); header('Content-Length: ' . $contentLength); if ($forceDownload) { header('Content-Disposition: attachment; filename="' . rawurlencode($fancyName). '"');//汉字自动转为URL编码 header('Content-Disposition: attachment; filename="' . $fancyName. '"'); }
header("Content-Transfer-Encoding: binary"); $bufferSize = 2048;
if ($speedLimit != 0) { $packetTime = floor($bufferSize * 1000000 / $speedLimit); }
$bytesSent = 0; $fp = fopen($fileName, "rb"); fseek($fp, $startPos);
//fpassthru($fp); while ($bytesSent < $contentLength && !feof($fp) && connection_status() == 0 ) { if ($speedLimit != 0) { list($usec, $sec) = explode(" ", microtime()); $outputTimeStart = ((float)$usec + (float)$sec); }
$readBufferSize = $contentLength - $bytesSent < $bufferSize ? $contentLength - $bytesSent : $bufferSize; $buffer = fread($fp, $readBufferSize);
echo $buffer;
ob_flush(); flush();
$bytesSent += $readBufferSize; if ($speedLimit != 0) { list($usec, $sec) = explode(" ", microtime()); $outputTimeEnd = ((float)$usec + (float)$sec); $useTime = ((float) $outputTimeEnd - (float) $outputTimeStart) * 1000000; $sleepTime = round($packetTime - $useTime); if ($sleepTime > 0) { usleep($sleepTime); } } }
return true; } ?>