<?php
//$file 为下载的文件,此处写死了,也可以用url传送请求
$file = "./test.txt";
//$file = $_GET['file'];

if(!file_exists($file)){
    header("HTTP/1.1 404 Not Found");
    die("The file has not existed");
}

$fname = basename($file);//文件名
$fhandle = fopen($fname,'rb');//文件句柄
$fsize = filesize($file);//文件大小

//断点续传和整个文件下载的判断,支持多段下载
if(!empty($_SERVER['HTTP_RANGE'])){
   // preg_match("/^bytes=([0-9]+)-([0-9]*)$/i", $_SERVER['HTTP_RANGE'], $match);
    $range = str_replace("=", "-", $_SERVER['HTTP_RANGE']);
    $match = explode("-", $range);
 $start = $match[1];
    $end = !empty($match[2]) ? $match[2] : $fsize - 1;
}else{
    $start = 0;
    $end = $fsize - 1;
}

if(($end - $start) < ($fsize - 1)){
 fseek($fhandle, $start);
 header("HTTP/1.1 206 Partial Content");
 header("Content-Length: " . ($end - $start + 1));
 header("Content-Range: bytes " . $start . "-" . $end . "/" . $fsize);
}else{
    header("HTTP/1.1 200 OK");
 header("Content-Length: $fsize");
 Header("Accept-Ranges: bytes");
}

header("Content-Type: application/octet-stream");
header("Content-Disposition: p_w_upload;filename=$fname");

if(!feof($fhandle)){
    set_time_limit(0);
    $buffer = fread($fhandle, $end - $start + 1);
    echo $buffer;
    flush();
    ob_flush();
}
?>
在linux下测试此断点下载用curl命令即可完成

假设,test.txt文件大小为86B

首先我们用md5sum(test.txt) 取得test.txt的md5值,作为和以后分段下载比较。

我们分三段下载,(1) curl -v -r 0-20 "url" > /tmp/test1,下载的文件大小为21字节,同时输出的信息存储在文件test里。

(2) curl -v -r 21-40 "url" > /tmp/test2

(3) curl -v -r 41-85 "url" >/tmp/test3

(4)合并test1,test2,test3,为一个文件 cat /tmp/test1 /tmp/test2  /tmp/test3 > /tmp/test4

求test4 的md5值 md5sum(/tmp/test4)和test的md5值比较 若相同则断点下载成功