PHP

【PHP】php文件下载限速,文件断点续传,多线程下载文件原理解析

小破孩
2022-06-23 / 0 评论 / 148 阅读 / 正在检测是否收录...
文件下载限速
------
首先,我们写一段使用php输出文件给浏览器下载的代码

    <?php
    /**
     * Created by PhpStorm.
     * User: tioncico
     * Date: 19-2-4
     * Time: 下午4:30
     */
    $filePath = './hyxd.zip';//文件
    $fp=fopen($filePath,"r");
    
    //取得文件大小
    $fileSize=filesize($filePath);
    
    header("Content-type:application/octet-stream");//设定header头为下载
    header("Accept-Ranges:bytes");
    header("Accept-Length:".$fileSize);//响应大小
    header("Content-Disposition: attachment; filename=testNaame");//文件名
    
    $buffer=1024;
    $bufferCount=0;
    
    while(!feof($fp)&&$fileSize-$bufferCount>0){//循环读取文件数据
        $data=fread($fp,$buffer);
        $bufferCount+=$buffer;
        echo $data;//输出文件
    }
    
    fclose($fp);
可以看出,php实现浏览器下载文件,主要是靠header头的支持以及echo 文件数据,那么,该如何限制速度呢?可以通过限制输出频率吗?例如每次读取1024之后,就进行一次sleep?

    <?php
    /**
     * Created by PhpStorm.
     * User: tioncico
     * Date: 19-2-4
     * Time: 下午4:30
     */
    $filePath = './hyxd.zip';//文件
    $fp=fopen($filePath,"r");
    
    //取得文件大小
    $fileSize=filesize($filePath);
    
    header("Content-type:application/octet-stream");//设定header头为下载
    header("Accept-Ranges:bytes");
    header("Accept-Length:".$fileSize);//响应大小
    header("Content-Disposition: attachment; filename=testName");//文件名
    
    $buffer=1024;
    $bufferCount=0;
    
    while(!feof($fp)&&$fileSize-$bufferCount>0){//循环读取文件数据
        $data=fread($fp,$buffer);
        $bufferCount+=$buffer;
        echo $data;//输出文件
        sleep(1);//增加了一个sleep
    }
    
    fclose($fp);
但是通过浏览器访问,我们发现是不行的,甚至造成了浏览器只有在n秒之后才会出现下载确认框,是哪里出了问题呢?

其实,这是因为php的buffer引起的,php buffer缓冲区,会使php不会马上输出数据,而是需要等缓冲区满之后才会响应到web服务器,通过web服务器再响应到浏览器中,详细请看:关于 [php的buffer(缓冲区)][1] 

那该怎么改呢?其实很简单,只需要使用ob系列函数就可解决:

    <?php
    /**
     * Created by PhpStorm.
     * User: tioncico
     * Date: 19-2-4
     * Time: 下午4:30
     */
    $filePath = './hyxd.zip';//文件
    $fp=fopen($filePath,"r");
    
    //取得文件大小
    $fileSize=filesize($filePath);
    
    header("Content-type:application/octet-stream");//设定header头为下载
    header("Accept-Ranges:bytes");
    header("Accept-Length:".$fileSize);//响应大小
    header("Content-Disposition: attachment; filename=testName");//文件名
    ob_end_clean();//缓冲区结束
    ob_implicit_flush();//强制每当有输出的时候,即刻把输出发送到浏览器
    header('X-Accel-Buffering: no'); // 不缓冲数据
    $buffer=1024;
    $bufferCount=0;
    
    while(!feof($fp)&&$fileSize-$bufferCount>0){//循环读取文件数据
        $data=fread($fp,$buffer);
        $bufferCount+=$buffer;
        echo $data;//输出文件
        sleep(1);
    }
    
    fclose($fp);
这样,我们就已经实现了,每秒只输出1024字节的数据:
我们可以增加下载速度,把buffer改成更大的值,例如102400,那么就会变成每秒下载100kb:
0

评论 (0)

取消