• 一个超好用的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;
    }
     ?>
  • 相关阅读:
    孙剑云访谈【转载】
    继承几近失传的经典吟诵-余觉中
    俞净意公遇灶神记
    吟诵,不为吟诵
    .NET中使用Redis
    redis密码设置、访问权限控制等安全设置
    Mock框架
    日记 2016年8月9日(周二)
    Notepad++前端开发常用插件介绍
    [Android Tips] 8. Install apk on multiple connected devices
  • 原文地址:https://www.cnblogs.com/liangyeyue/p/4155596.html
Copyright © 2020-2023  润新知