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程序设计有一定的借鉴价值。