分享一个超好用的php header下载函数_php教程-查字典教程网
分享一个超好用的php header下载函数
分享一个超好用的php header下载函数
发布时间:2016-12-29 来源:查字典编辑
摘要:复制代码代码如下:

复制代码 代码如下:

<?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;

}

?>

相关阅读
推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
  • 大家都在看
  • 小编推荐
  • 猜你喜欢
  • 最新php教程学习
    热门php教程学习
    编程开发子分类