php实现的支持断点续传的文件下载类
本文实例讲述了php实现的支持断点续传的文件下载类及其用法,是非常实用的技巧。分享给大家供大家参考。具体方法如下:
通常来说,php支持断点续传,主要依靠HTTP协议中headerHTTP_RANGE实现。
HTTP断点续传原理:
Http头Range、Content-Range()
HTTP头中一般断点下载时才用到Range和Content-Range实体头,
Range用户请求头中,指定第一个字节的位置和最后一个字节的位置,如(Range:200-300)
Content-Range用于响应头
请求下载整个文件:
GET/test.rarHTTP/1.1
Connection:close
Host:116.1.219.219
Range:bytes=0-801//一般请求下载整个文件是bytes=0-或不用这个头
一般正常回应:
HTTP/1.1200OK
Content-Length:801
Content-Type:application/octet-stream
Content-Range:bytes0-800/801//801:文件总大小
FileDownload.class.php类文件代码如下:
<?php /**php下载类,支持断点续传 *Date:2013-06-30 *Author:test *Ver:1.0 * *Func: *download:下载文件 *setSpeed:设置下载速度 *getRange:获取header中Range */ classFileDownload{//classstart private$_speed=512;//下载速度 /**下载 *@paramString$file要下载的文件路径 *@paramString$name文件名称,为空则与下载的文件名称一样 *@paramboolean$reload是否开启断点续传 */ publicfunctiondownload($file,$name='',$reload=false){ if(file_exists($file)){ if($name==''){ $name=basename($file); } $fp=fopen($file,'rb'); $file_size=filesize($file); $ranges=$this->getRange($file_size); header('cache-control:public'); header('content-type:application/octet-stream'); header('content-disposition:attachment;filename='.$name); if($reload&&$ranges!=null){//使用续传 header('HTTP/1.1206PartialContent'); header('Accept-Ranges:bytes'); //剩余长度 header(sprintf('content-length:%u',$ranges['end']-$ranges['start'])); //range信息 header(sprintf('content-range:bytes%s-%s/%s',$ranges['start'],$ranges['end'],$file_size)); //fp指针跳到断点位置 fseek($fp,sprintf('%u',$ranges['start'])); }else{ header('HTTP/1.1200OK'); header('content-length:'.$file_size); } while(!feof($fp)){ echofread($fp,round($this->_speed*1024,0)); ob_flush(); //sleep(1);//用于测试,减慢下载速度 } ($fp!=null)&&fclose($fp); }else{ return''; } } /**设置下载速度 *@paramint$speed */ publicfunctionsetSpeed($speed){ if(is_numeric($speed)&&$speed>16&&$speed<4096){ $this->_speed=$speed; } } /**获取headerrange信息 *@paramint$file_size文件大小 *@returnArray */ privatefunctiongetRange($file_size){ if(isset($_SERVER['HTTP_RANGE'])&&!empty($_SERVER['HTTP_RANGE'])){ $range=$_SERVER['HTTP_RANGE']; $range=preg_replace('/[\s|,].*/','',$range); $range=explode('-',substr($range,6)); if(count($range)<2){ $range[1]=$file_size; } $range=array_combine(array('start','end'),$range); if(empty($range['start'])){ $range['start']=0; } if(empty($range['end'])){ $range['end']=$file_size; } return$range; } returnnull; } }//classend ?>
demo示例代码如下:
<?php require('FileDownload.class.php'); $file='book.zip'; $name=time().'.zip'; $obj=newFileDownload(); $flag=$obj->download($file,$name); //$flag=$obj->download($file,$name,true);//断点续传 if(!$flag){ echo'filenotexists'; } ?>
断点续传测试方法:
使用linuxwget命令去测试下载,wget-c-Ofilehttp://xxx
1.先关闭断点续传
$flag=$obj->download($file,$name);
test@ubuntu:~/Downloads$wget-Otest.rarhttp://demo.test.com/demo.php --2013-06-3016:52:44--http://demo.test.com/demo.php 正在解析主机demo.test.com...127.0.0.1 正在连接demo.test.com|127.0.0.1|:80...已连接。 已发出HTTP请求,正在等待回应...200OK 长度:10445120(10.0M)[application/octet-stream] 正在保存至:“test.rar” 30%[============================>]3,146,580513K/s估时14s ^C test@ubuntu:~/Downloads$wget-c-Otest.rarhttp://demo.test.com/demo.php --2013-06-3016:52:57--http://demo.test.com/demo.php 正在解析主机demo.test.com...127.0.0.1 正在连接demo.test.com|127.0.0.1|:80...已连接。 已发出HTTP请求,正在等待回应...200OK 长度:10445120(10.0M)[application/octet-stream] 正在保存至:“test.rar” 30%[============================>]3,146,580515K/s估时14s ^C
可以看到,wget-c不能断点续传
2.开启断点续传
$flag=$obj->download($file,$name,true);
test@ubuntu:~/Downloads$wget-Otest.rarhttp://demo.test.com/demo.php --2013-06-3016:53:19--http://demo.test.com/demo.php 正在解析主机demo.test.com...127.0.0.1 正在连接demo.test.com|127.0.0.1|:80...已连接。 已发出HTTP请求,正在等待回应...200OK 长度:10445120(10.0M)[application/octet-stream] 正在保存至:“test.rar” 20%[==================>]2,097,720516K/s估时16s ^C test@ubuntu:~/Downloads$wget-c-Otest.rarhttp://demo.test.com/demo.php --2013-06-3016:53:31--http://demo.test.com/demo.php 正在解析主机demo.test.com...127.0.0.1 正在连接demo.test.com|127.0.0.1|:80...已连接。 已发出HTTP请求,正在等待回应...206PartialContent 长度:10445121(10.0M),7822971(7.5M)字节剩余[application/octet-stream] 正在保存至:“test.rar” 100%[++++++++++++++++++++++++=========================================================================>]10,445,121543K/s花时14s 2013-06-3016:53:45(543KB/s)-已保存“test.rar”[10445121/10445121])
可以看到会从断点的位置(%20)开始下载。
本文实例完整源码可点击此处本站下载。
相信本文所述对大家的PHP程序设计有一定的借鉴价值。