分享一个超好用的php header下载函数
<?php
/**
* 发送文件
*
* @author: legend(legendsky@hotmail.com)
* @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;
}
?>