PHP实现大文件断点下载荐

什么是断点续传下载

 就是下载文件时,不必重头开始下载,而是从指定的位置继续下载,这样的功能就做断点续传下载。断点续传的理解可以分为两部分:一部分是断点,一部分是续传下载。断点的由来是在下载过程中,将一个下载文件分成了多个部分,同时进行多个部分一起的下载,当某个时间点,任务被暂停了或因网络原因断网、或停电断点续传河汉、程序闪退或退出等等影响,此时下载中断的位置就是断点了。续传就是当一个未完成的下载任务再次开始时,会从上次的断点继续传送下载。当然,在实际php架构师的业务开发中,断点续传by河汉就是把一个大文件事先分成多个小片段返回给前端。

简单介绍下HTTP断点续传原理

  PHP支持断点续传,主要依靠HTTP协议中php架构师 header HTTP_Rphp是什么语言ANGE实现。HT文件恢复大师TP断点续传原理Http头 Range、Content-Range()HTTP头中一般断点下载时才用到Range和Content-Range实体头,Range用户请求头中,指定第一个字节的位置和最后一个字节的位置,如(Range:200-300)Content-Range用于响应头请求下载整个文件。

不使用断点续传

ge点下一步t  /dphpown.zip   http/1.1
accept: image/gif,image/x-xbitmap,image/jpeg,image/pjpeg,application/vnd.ms-excel,application/msword,application/vnd.ms-powerpoint
accept-language:zh-cn
accept-encoding:gzip,deflate
user-agent:mozilla/4.0(compatible;msie  5.01;windows nt 5.0)
connection:keep-alive

php音乐系统
服务器收到请求后,按要求寻找请求的文件,提交文件的信息,然后返回给浏点下览器,返回信息如下:

HTTP/1.1  200   OK
content - length = 106788888
accept - rphp音乐系统anges = bytes
date=monphp培训, 30  apr   2021  12:12:11  gmt
etag=w/“02ca57e173c11:95b”
conte下载微信nt - type = applicatio断点张敬轩n/octet - stream
server = microsoft - iis /5.0
last-mo点下卞dified = mon, 30  apr  2021文件  12:12:11  gmt

使用断点续传

G点下卞怎么念ET   /down.zip   HTTP/1.0
User - Agent : Netphp面试题Fox
RANGE: bytes = 2000070-点下开票app
Accept:text/html,image/点下代开gif,image/jpeg,*;q=.2,*/*;q=.2

多了这么一行Range:bytes = 2000070-
这一行的意思就是告诉服务器点下卞怎么念down.zip这个文件从2000070字节开始传,前面的字节不用传了。
Range的完整格式是:

Range:bytes = startOffset - targetOffset/sum   [表示从startOffset读取,一直读取到targetOffset位置,读取总数为sum]
Range:bytes = startOffset - targetOffset   [字节总数也可以去掉php教程]

服务器收到这个请求后,返回的信息如下:

HTTP/1.1   206    Partiphpstudyal    Content
content - length = 106788888
content - range = bytes   2000070 - 106788888 / 106788889
date = mon,文件格式  30   ap文件管理器r    2021    12:点下卞怎么念55:20   gm文件夹怎么压缩t
etag = w/“02ca57e173c11:95b”
c断点ontent - type = applicat下载支付宝ion / octet - stream
server = microsoft - iis / 5.0
last - m断点续传odified = mon下载支付宝,   30   apr   2021  12:55:20   gmt

和前面服务器返回的信息比较一下,就会发现增加了一行:

Co点下ntent - Range = bytes   2000070 - 106788888 / 106788889

返回的代点下开票app码也改为206了,而下载不再是200了。

HTTP/1.1   206  Partial   Content

增加校验

 在实际场景中,会出现一种情况,即在终端发起续传请求时,URL对应的文件内容在服务端已经发生了变化,此时续传的数据肯定点下开票app是错误点下的拼音的。如何解决这个问题呢?显然此文件夹加密时需要有一个标识文文件恢复大师件唯一性的方法。
 在 RFC2616 中也有相应的定义,比如实现 Last-Mod断点ified 来标识文件的最后修改时间,这样既可判下载抖音极速版断出下载微信续传文件时是否已经发生过改动。同时 FC2616 中还定义有一个ETag 的头,点下开票app可以使用 ETag 头来放置文件的唯一标识,比如文件的MD5值。
 终端在发起续传请求时应该在HTTP头中申明If点下一步-Match 或者 If-Modified-Since 字段,帮助服务端判别文件变化。
 另外RF2616中同时定义有一个If-Range断点歌曲原唱头,终端如果在续传是使用If-Range。If-Range中的内容可以为最初收到的ETag头或是Last-Modified中的最后修改时候。服务端在收到续传请求时,通过If-Range中的内容进行校验,校验一致时返回206的续传回应,不一致时服务端则返回200回应,回应的内容为新的文件的全部数据。

Last-Modified

 If-Modified-文件Since,和 Last-Modified 一样都是点下用于记录页面最后修改时间的 HTTP 头信息,只是 Last-Modified 是由服务器往客户端发送的 HTTP 头,而 If-Modified-Since 则是由客户端往服务器发送的头,可以看到,再次请求本地存在的 cache 页面时,客户端会通过 If-Modified-Since 头将先前服务器端发过来的 Last-Modified 最后修改时间戳发送回去,这是为了让服务器端进行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是断点歌词最新的,则返回新的内容,如果是最新的,则返回 304 告诉客户端其本地 cach断点原唱e 的页面或文件是最新的,于是客户端就可以直接从本下载百度地加载页面了,这样在网络上传输的数据就会大大断点歌词减少,同时也减轻了服务器的负担。

Etag

 Etag(Etity Tags断点歌曲原唱)主要为了解决 Last-Modified 无法解决的断点吉他谱一些问题。
 1. 一些文件也许会周期性的更改,但是内容并不改变(仅改变修改时间),这时候我们并不希点下面的四个点怎么打望客户端认为这个文件被修改了,而重新 GET 。文件
 2.某些文件修改非常频繁,例如:在秒以下的时间内进行修改(1s内修改了N次),If-Modified-Since 能检查到的粒度是断点续传 s 级的,这文件传输助手种修改无法判断(或者说 UNIX 记录 MTIME 只能精确到秒)。
 3.某些服务器不能精确的得到文件的最后修改时间。
 为此,HTTP/1.1 引入了 Etag。Etag 仅仅是一个和文件相关的标记,可以是一个版本标记,例如:v1.0.0;或者说“627-45235gf点下面的四个点怎么打d56250”这么一串看起来很神秘的下载微信编码。但是 HTTP/1.1 标准并没有规定 Etag 的内容是什么或者说要怎么实现,唯一规定的是 Etag 需要放在 “” 内。

If-Range

用于判断实体是否发生改变,如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。
一般格式:

If-Range:Etag | HTT文件怎么压缩打包发送P-Date

也就是说,If-Range 可以使用 Etag 或者 Last-Modified 返回的值。当没有 ETage 却有 Last-modified 时,可以把 Last-modified 作为 If-Range 字段的值。
例如:

If-Range:Etag | HT断点续传txtTP-Date

也就是说,If-Range 可以使用 Etag 或者 Last-Modified 返回的值。当没有 ETag 却有 Last-modified时,可以把 Lasphp架构师t-modified 作为 If-Range 字段的值。
例如:

If-Range:“627-45235gfd56250”
If-Rphp是什么语言ange:30   apr断点吉他谱    2021    12:55下载:20   gmt

If-Range 必须与 Range 配套使用。如果请求下载抖音报文中没有 Range,那么 If-Range 就会被忽略。如果服务器不支持 If-点下的拼音Range,那么 Range 也会被忽略。
如果请求报文中的 Etag 与服务器目标内容的 Etag 相等,即没有发生变化,那么应答报文的状态码为206。如果服务器目标内容发php面试题生了变化,那么应答报断点续传文的状态码为200.
用于校验的其他 HTTP 头信息:If-Match/If-None-Match、If-Modified-Since/If-Unmodified-文件夹图片Since。

工作原理

Etag 由服务器端生成,客户端通过 If-Range 条件判断请求来验证资源是否修改。请求一个文件的流程如下:
第一次请求:
 1.客户端发起 HTTP GET 请求一个文件。
 2.服务器处理请求,返回文件内容以及相应的 Header,其中php架构师包括 Etag (例如:627-45235gfd56250)(假设服务器支持 Etag 生成并已开启了 Etag)状态码为200。
第二次请求(断点续传):
 1.客户端发起 HTTP GET 请求一个文件,同时发送点下一步 If-Range (该头的内容就是第一次请求时服务器返回的 Etag:627-下载微信45235gfd56250)。
 2.服务器判断接收到的 Etag 和计算出来的 Etag点下方 是否匹配,如果匹配,那么响应的状态码为206;否则,状态码为200。

接下来上代码:

<?php
/* p点下的拼音hp下载类,支持断点续传
download: 下载文件
setSpeed:  设置下载速度
getphp教程Range: 获取header断点张敬轩中Range
*/
class  FileDownload{
pr下载万能钥匙ivate $_s断点续传txtpeed = 512;                //下载速度
/** 下载
*   @ param  String     $file            要下载的文件路径
*   @ param  String     $name        文件名称,为空则与下载的文件名称一样
*   @ param  boolean  $reload       是否开启断点续传
*/
public  func下载万能钥匙tion   do断点续传wnload($file, $name=' ', $reload=false){点下户
if(file_exists($file)){
if($name==' '){
$name = basename($file);
}
$header_array = get_headers($file, true);
//断点是什么意思下载本地文件,获取文件大小
if(!$header_点下念什么array){
$file_size = filesize($file);
}else{
$file_size = $hea文件夹图片der_array['C点下面的四个点怎么打ontent-Length'];
}
$ranges = $this->getRange($file_size);
$ua =文件夹加密 $_SERVER['H断点吉他谱TTP_USER_AGENT'];//判断是什么类型浏览器
header('cache-c下载万能钥匙ontrol:public');
header('co文件ntent-type:application/o断点续传by河汉ctet-stream');
header('content-disposit下载快手ion:att下载抖音极速版achment; filename='.$name);
$encoded_filename = urlencode($name);
$encoded_filename = str_replace("+","%20",$encoded_fi文件夹怎么压缩lename);
//解决下载断点文件名乱码
if(preg_match("/MSIE/",$ua) ||  preg_match("/Trident/", $ua)){
header('Content-D文件管理isposition:attachment; filen文件夹加密ame=" ' .$encoded_filename . ' " ')
}else if(preg_match("/Fi点下念什么refox", $ua)) {
header('Conte点下nt-Disposition:php培训 attachment; filename*="utf8 ' ' ' . $name . ' " ');
}else if(断点preg断点歌词_match("/Chrome/", $ua)) {
header('Content-Disposition: atta点下方chment; filename=" ' . $encoded_filename . ' " '文件管理);
} else{
headerphp是什么语言('Content-D下载支付宝isposition: attachment; file断点续传by河汉name=" '.);
}
if($reload  &&  $ranges != null){       //使用续传
header('HTTP/1.1   206   Partial  Content' );
heade文件管理r('Accept-Ranges:bytes' );
//剩余长度
header(spr点下念什么intf('content-length:%u',$ranges['end']-$ranges['start']));
//range信息
header(sprintf('co点下面的四个点怎么打ntent-range:点下代开bytes  %s-%s/%s', $ranges['start'], $ranges['end'], $file_size));
//fp指针跳到断点位置
fseek($fp, sprintf('%u', $ranges['start']));
}else{
header('HTTP/1.1   200   OK');
header('content-length断点续传:'.$file_size);
}
while(下载快手!feof($fpphp是什么语言)){
echo   fread($fp,  round($this->_speed*1024,0));
ob_fl断点是什么意思ush();
//sleep(1);             //用于测试,减慢下载速度
}
($fp!=null)点下户   &&   fclose($fp);
}else{断点张敬轩
return ' ';
}
}
/*点下卞*   设置下载速度
*    @断点续传txt param   int   $speed
*/
public  function  setSpeed($speed){
if(is_numberic($speed)   &&    $speed  >  16   &&   $speed &l下载qqt; 4096){
$this->_speed = $speed;
}
}
/**   获取header   range信息
*    @ param     int    $下载file_size   文件大文件小
*    @ return      Array
*/
priv下载微信ate   function  getRang点下e($file_size){
if(isset($_SERVER['HTTP_RANGE'])  &a点下念什么mp;&  !e文件怎么压缩打包发送mpt点下卞y($_SERVER['HTTP_RANGE'])){
$rangphp文件用什么软件打开e = $_SERVER['HTTP_RANGE'];
$range = preg_repl断点张敬轩ace('/[s|,].*断点原唱/', ' ', $range);
$range = explode('-', substr($range, 6));
if(count($range) < 2){
$ran文件管理器ge[1] = file_size;
}
$range = array_combine(arra断点张敬轩y('start','end'), $range);
if(empty($range['start'])) {
$range['start']  = 0;
}
if(empty($range[php教程'end'])) {
$rangphp货币e['end'] = $fiphp音乐系统le_size;
}
return   $range;
}
return  null断点吉他谱;
}
}
$file  =  'down.zip';
$name  =  time().'.zip';
$obj  =  new  FileDownload();
$flag  = $obj->download($file, $name);
//$flag  =  $obj->downl文件格式oad($file, $name, true)phpstudy;   //断点续传
if(!$flag){
echo  'file  not  exists';
}
?&文件夹图片gt;