发送文件的函数

/**
 * 发送文件
 *
 * @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 $startPos;
            
$endPos $endPos $fileSize $fileSize $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). '"');
    }

    
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() == )
    {
        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;
}  
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值