百度网盘下载功能的后端实现-PHP

百度⽹盘下载功能的后端实现-PHP
百度⽹盘下载功能的后端实现-PHP
主要阐述⼀下
1、超⼤⽂件如何下载才合理
2、实现分段下载
3、实现极速上传到我的⽹盘
4、实现下载限速
⽂件下载我们⼀般是在后台下载excel⽤的⽐较多,⽂件不⼤,单次下载,基本的⽅式就能解决了,但是当我们要专门提供下载服务的时候,就应该多考虑⼀些。
⽂件:$file = ‘D:/software/ideaIU-2019.’;// ⼤⼩:561M
⼀、超⼤⽂件如何下载才合理
⽅法1:
使⽤readfile,它会将⽂件分块读取到输出缓冲区,如果缓冲区满了,⾃然就会响应到客户端,形成⼀种流式的⽂件传输。
<?php
header('Content-Disposition: attachment; filename="ideaIU-2019."');
$file='D:/software/ideaIU-2019.';// ⼤⼩:561M
readfile($file);
⽅法2:
使⽤file_get_contents分块读取,输出
对于$file,我们⽆法⼀次性将其加⼊内存,然后输出到输出流,即使我们调整了内存⼤⼩可以加载,当多个请求同时来下载这个⽂件时也是不⾏的。所以需要分段加载进内存然后输出。
php输出缓冲区⼤⼩默认为4086Byte,也就是4kb,我们就⼀次读取4kb。输出缓冲区也是要等到满了之后或者程序执⾏结束才响应给web服务器的,因为这样可以较少⽹络IO次数。
<?php
header('Content-Disposition: attachment; filename="ideaIU-2019."');
flush();
$file='D:/software/ideaIU-2019.';// ⼤⼩:561M
$buffer='';
$len=4096;// 4k
$step=0;
do{
$start=$step*$len;
$buffer=file_get_contents($file,false,null,$start,$len);
file_put_contents('php://output',$buffer);
$step++;
}while($buffer);
flush()函数的作⽤是⼈为的将缓冲区的内容响应出去,这样做的好处是使⽤户体验更友好。假如我们要导出⼀个表格,我们要1、设置header,2、读数据库,运算得出结果,3、按照excel协议输出;如果计算复杂的话,⽤户要等待不少时间才能看到浏览器弹出下载,因为header的设置不⾜以把缓冲区填满,要等到步骤3的写⼊,所以这段时间内浏览器是接收不到任何响应的,因为浏览器是需要接收到header才能知道是⼀个下载任务,才知道弹出下载的,所以使⽤flush()⽅法可以提前让⽤户看到下载的提⽰,当然对于我们这种单纯下载的功能使不使⽤flush()效果不明显。
⼆、实现分段下载
百度云盘的下载会将你本次下载的进度保存起来,即使你重新登录了也不影响继续下载,这就是分段下载,实现起来也很简单,客户端需要保留上次下载到哪⾥了,再次下载的时候传参就好了。
<?php
header('Content-Disposition: attachment; filename="ideaIU-2019."');
flush();
$file='D:/software/ideaIU-2019.';// ⼤⼩:561M
$buffer='';
$len=4096;// 4k
$step=0;
$history=$_GET['history']??0;// 或者通过header传参
do{
$start=$step*$len+$history;
$buffer=file_get_contents($file,false,null,$start,$len);
file_put_contents('php://output',$buffer);
$step++;
}while($buffer);
三、实现极速上传到我的⽹盘
当我们点击别⼈的资源保存到我的⽹盘时,实际上保存的就是⼀个映射,⼀条记录,将这个⽂件的编码保存到我的名下,⽽删除的话删除的也是记录,⽽不是实体⽂件,实际上服务器上同⼀个⽂件只需要保存⼀份就可以了(当然会有备份)。
有时候我们从本地上传⼀个⽂件到⽹盘速度很快,⼀闪就好了,有时候却是要上传很久,这是为什么呢?
当我们在php官⽹下载php包的时候,每个包下⾯后有⼀个哈希编码,⽤以保证这个⽂件没有被篡改过,⽤户可以对这个⽂件使⽤哈希运算来对⽐哈希值。此处也是⼀样,只要你要上传的⽂件哈希值已经存在了,就可以判断你要上传的⽂件存在服务器上了,就不⽤再次上传了,只需要给你加个记录就好了,
四、实现下载限速
下载限速是⼀个很恶⼼的东西,它的实现也很简单。
假如要限制你的速度为100k/s,只需要控制在1秒的时间内只给你100k的数据,多了没有。
限速的前提是,原始的速度肯定⼤于这个速度,否则没有限制的必要了。
<?php
header('Content-Disposition: attachment; filename="ideaIU-2019."');
flush();
$file='D:/software/ideaIU-2019.';// ⼤⼩:561M
$buffer='';
$len=102400;// 100k/s
$step=0;
$history=$_GET['history']??0;// 或者通过header传参
do{
$t1=microtime(true);
$start=$step*$len+$history;
$buffer=file_get_contents($file,false,null,$start,$len);
file_put_contents('php://output',$buffer);
flush();// 做到精确控制,防⽌数据不够填满缓冲区
$t2=microtime(true);
$t=intval((1-($t2-$t1))*1000000);
if($t>0){
usleep($t);
}
$step++;
}while($buffer);

本文发布于:2024-09-20 14:55:17,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/3/90157.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:下载   缓冲区   实现   输出   需要   响应   分段   浏览器
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议