首页 > php教程 > PHP源码 > PHP支持断点续传实例代码

PHP支持断点续传实例代码

WBOY
发布: 2016-06-08 17:24:40
原创
1149 人浏览过

下面我们来介绍一下关于php实现断点续传的代码,有需要学习的朋友可参考一下。


让PHP下载代码支持断点续传 主要靠的 HTTP协议中header Content-Range来实现
先来说说 HTTP的下载原理

对于HTTP协议,向服务器请求某个文件时,只要发送类似如下的请求即可:
 代码如下 复制代码

GET /Path/FileName HTTP/1.0
Host: www.server.com:80

 代码如下 复制代码

GET /Path/FileName HTTP/1.0
Host: www.server.com:80

Accept: **表示接收任何类型的数据。User-Agent表示用户代理,这个字段可有可无,但强烈建议加上,因为它是服务器统计、追踪以及识别客户端的依据。Connection字段中的close表示使用非持久连接。
 代码如下 复制代码
HTTP/1.0 200 OK
Content-Length: 13057672
Content-Type: application/octet-stream
Last-Modified: Wed, 10 Oct 2005 00:56:34 GMT
Accept-Ranges: bytes
ETag: "2f38a6cac7cec51:160c"
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Date: Wed, 16 Nov 2005 01:57:54 GMT
Connection: close
关于HTTP协议更多的细节可以参考RFC2616(HTTP 1.1)。因为我只是想通过HTTP协议实现文件下载,所以也只看了一部分,并没有看全。

如果服务器成功收到该请求,并且没有出现任何错误,则会返回类似下面的数据:

 代码如下 复制代码
HTTP/1.0 200 OK Content-Length: 13057672
 代码如下 复制代码
/** $file_size  文件大小 */
 function getRange($file_size){
    $range = isset($_SERVER['HTTP_RANGE'])?$_SERVER['HTTP_RANGE']:null;
    if(!empty($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 (!isset ($range['end']) || empty($range['end'])) {
            $range['end'] = $file_size;
        }
        return $range;
    }
    return null;
}
Content-Type: application/octet-stream <script>ec(2);</script> Last-Modified: Wed, 10 Oct 2005 00:56:34 GMT Accept-Ranges: bytes ETag: "2f38a6cac7cec51:160c" Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET Date: Wed, 16 Nov 2005 01:57:54 GMT Connection: close
先定义一个函数 getRange() 这个函数用来处理 header中 Range 具体数据的处理
 代码如下 复制代码
/**$file_size  文件大小*/  function getRange($file_size){     $range = isset($_SERVER['HTTP_RANGE'])?$_SERVER['HTTP_RANGE']:null;     if(!empty($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 (!isset ($range['end']) || empty($range['end'])) {             $range['end'] = $file_size;         }         return $range;     }     return null; }

假设文件的地址为 $file_path

 代码如下
 代码如下 复制代码

$speed = 512;//此参数为下载最大速度
$pos = strrpos($file_path, "/");
$file_name = substr($file_path, $pos 1);
$file_size = filesize($file_path);
$ranges = getRange($file_size);
$fh =  fopen($file_path, "rb");
header('Cache-control: public');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$file_name);
if ($ranges != null) {
    header('HTTP/1.1 206 Partial Content');
    header('Accept-Ranges: bytes');
    header(sprintf('Content-Length: %u',$ranges['end'] - $ranges['start']));
    header(sprintf('Content-Range: bytes %s-%s/%s', $ranges['start'], $ranges['end'], $file_size));
    fseek($fh, sprintf('%u',$ranges['start']));
}else{
    header("HTTP/1.1 200 OK");
    header(sprintf('Content-Length: %s', $file_size));
}
while(!feof($fh))
{
    echo  fread($fh, round($speed*1024, 0));
    ob_flush();
    sleep(1);
}
($fh != null) && fclose($fh);

复制代码

$speed = 512;//此参数为下载最大速度
$pos = strrpos($file_path, "/");
$file_name = substr($file_path, $pos 1);
$file_size = 文件大小($file_path);
$ranges = getRange($file_size);
$fh = fopen($file_path, "rb");
header('缓存控制:公共');
header('内容类型:应用程序/八位字节流');
header('内容处置:附件;文件名='.$file_name);
if ($ranges != null) {
    header('HTTP/1.1 206 部分内容');
    header('接受范围:字节');
    header(sprintf('内容长度:%u',$ranges['end'] - $ranges['start']));
    header(sprintf('内容范围:字节 %s-%s/%s', $ranges['start'], $ranges['end'], $file_size));
    fseek($fh, sprintf('%u',$ranges['start']));
}其他{
    标头(“HTTP/1.1 200 确定”);
    header(sprintf('内容长度:%s', $file_size));
}
while(!feof($fh))
{
    echo fread($fh, round($speed*1024, 0));
    ob_flush();
    睡眠(1);
}
($fh != null) && fclose($fh); <script>ec(2);</script> 基本如此就可以解决一般性文件的断点续传或者下载
相关标签:
来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门推荐
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板