文件下载限速

首先,我们写一段使用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(缓冲区)

那该怎么改呢?其实很简单,只需要使用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:

最后修改:2021 年 12 月 13 日 04 : 06 PM
对您有帮助的话,请赏包辣条吧 ^~^