ブレークポイント再開ダウンロードをサポートする PHP ファイル ダウンロード クラス

黄舟
リリース: 2023-03-05 19:52:02
オリジナル
1470 人が閲覧しました

php は、主に HTTP プロトコルのヘッダー HTTP_RANGE に依存して、ブレークポイントの再開をサポートしています。

HTTP ブレークポイントで再開可能なダウンロードの原則
HTTP ヘッダー Range、Content-Range()
一般に、Range および Content-Range エンティティ ヘッダーは、HTTP ヘッダーのブレークポイント ダウンロードにのみ使用されます。
Range ユーザー リクエスト ヘッダーは、位置を指定します最初のバイトと最後のバイトの位置 (範囲: 200-300)
Content-Range は応答ヘッダーで使用されます

ファイル全体のダウンロード要求:
GET /test.rar HTTP/1.1
接続: 閉じる
ホスト: 116.1.219.219
範囲: bytes=0-801 //ファイル全体をダウンロードする一般的なリクエストは bytes=0-、またはこのヘッダーを使用しないでください

通常は正常な応答
HTTP/1.1 200 OK
コンテンツ-長さ: 801
コンテンツ -タイプ: application/octet-stream
Content-Range: バイト 0-800/801 //801: 合計ファイル サイズ

FileDownload.class.php

<?php
/** php下载类,支持断点续传
*   Date:   2013-06-30
*   Author: fdipzone
*   Ver:    1.0
*
*   Func:
*   download: 下载文件
*   setSpeed: 设置下载速度
*   getRange: 获取header中Range
*/

class FileDownload{ // class start

    private $_speed = 512;   // 下载速度


    /** 下载
    * @param String  $file   要下载的文件路径
    * @param String  $name   文件名称,为空则与下载的文件名称一样
    * @param boolean $reload 是否开启断点续传
    */
    public function download($file, $name=&#39;&#39;, $reload=false){
        if(file_exists($file)){
            if($name==&#39;&#39;){
                $name = basename($file);
            }

            $fp = fopen($file, &#39;rb&#39;);
            $file_size = filesize($file);
            $ranges = $this->getRange($file_size);

            header(&#39;cache-control:public&#39;);
            header(&#39;content-type:application/octet-stream&#39;);
            header(&#39;content-disposition:attachment; filename=&#39;.$name);

            if($reload && $ranges!=null){ // 使用续传
                header(&#39;HTTP/1.1 206 Partial Content&#39;);
                header(&#39;Accept-Ranges:bytes&#39;);
                
                // 剩余长度
                header(sprintf(&#39;content-length:%u&#39;,$ranges[&#39;end&#39;]-$ranges[&#39;start&#39;]));
                
                // range信息
                header(sprintf(&#39;content-range:bytes %s-%s/%s&#39;, $ranges[&#39;start&#39;], $ranges[&#39;end&#39;], $file_size));
                
                // fp指针跳到断点位置
                fseek($fp, sprintf(&#39;%u&#39;, $ranges[&#39;start&#39;]));
            }else{
                header(&#39;HTTP/1.1 200 OK&#39;);
                header(&#39;content-length:&#39;.$file_size);
            }

            while(!feof($fp)){
                echo fread($fp, round($this->_speed*1024,0));
                ob_flush();
                //sleep(1); // 用于测试,减慢下载速度
            }

            ($fp!=null) && fclose($fp);

        }else{
            return &#39;&#39;;
        }
    }


    /** 设置下载速度
    * @param int $speed
    */
    public function setSpeed($speed){
        if(is_numeric($speed) && $speed>16 && $speed<4096){
            $this->_speed = $speed;
        }
    }


    /** 获取header range信息
    * @param  int   $file_size 文件大小
    * @return Array
    */
    private function getRange($file_size){
        if(isset($_SERVER[&#39;HTTP_RANGE&#39;]) && !empty($_SERVER[&#39;HTTP_RANGE&#39;])){
            $range = $_SERVER[&#39;HTTP_RANGE&#39;];
            $range = preg_replace(&#39;/[\s|,].*/&#39;, &#39;&#39;, $range);
            $range = explode(&#39;-&#39;, substr($range, 6));
            if(count($range)<2){
                $range[1] = $file_size;
            }
            $range = array_combine(array(&#39;start&#39;,&#39;end&#39;), $range);
            if(empty($range[&#39;start&#39;])){
                $range[&#39;start&#39;] = 0;
            }
            if(empty($range[&#39;end&#39;])){
                $range[&#39;end&#39;] = $file_size;
            }
            return $range;
        }
        return null;
    }

} // class end

?>
ログイン後にコピー

デモ

<?php

require(&#39;FileDownload.class.php&#39;);
$file = &#39;book.zip&#39;;
$name = time().&#39;.zip&#39;;
$obj = new FileDownload();
$flag = $obj->download($file, $name);
//$flag = $obj->download($file, $name, true); // 断点续传

if(!$flag){
    echo &#39;file not exists&#39;;
}

?>
ログイン後にコピー

ブレークポイントのダウンロードを再開するためのテスト方法:
Linux wgetコマンドを使用してダウンロードをテストします、wget -c -O file http://www.php.cn/

1. 最初にブレークポイント再開をオフにします Transfer
$flag = $obj->down​​load($file, $name);

fdipzone@ubuntu:~/Downloads$ wget -O test.rar http://www.php.cn/
--2013-06-30 16:52:44--  http://www.php.cn/
正在解析主机 demo.fdipzone.com... 127.0.0.1
正在连接 demo.fdipzone.com|127.0.0.1|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度: 10445120 (10.0M) [application/octet-stream]
正在保存至: “test.rar”

30% [============================>                                                                     ] 3,146,580    513K/s  估时 14s
^C
fdipzone@ubuntu:~/Downloads$ wget -c -O test.rar http://www.php.cn/
--2013-06-30 16:52:57--  http://www.php.cn/
正在解析主机 demo.fdipzone.com... 127.0.0.1
正在连接 demo.fdipzone.com|127.0.0.1|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度: 10445120 (10.0M) [application/octet-stream]
正在保存至: “test.rar”

30% [============================>                                                                     ] 3,146,580    515K/s  估时 14s
^C

可以看到,wget -c不能断点续传
ログイン後にコピー


2. ブレークポイント再開 transfer
$flag = $obj-> ;down​​load($file, $name, true);

fdipzone@ubuntu:~/Downloads$ wget -O test.rar http://www.php.cn/
--2013-06-30 16:53:19--  http://www.php.cn/
正在解析主机 demo.fdipzone.com... 127.0.0.1
正在连接 demo.fdipzone.com|127.0.0.1|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度: 10445120 (10.0M) [application/octet-stream]
正在保存至: “test.rar”

20% [==================>                                                                               ] 2,097,720    516K/s  估时 16s
^C
fdipzone@ubuntu:~/Downloads$ wget -c -O test.rar http://www.php.cn/
--2013-06-30 16:53:31--  http://www.php.cn/
正在解析主机 demo.fdipzone.com... 127.0.0.1
正在连接 demo.fdipzone.com|127.0.0.1|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 206 Partial Content
长度: 10445121 (10.0M),7822971 (7.5M) 字节剩余 [application/octet-stream]
正在保存至: “test.rar”

100%[++++++++++++++++++++++++=========================================================================>] 10,445,121   543K/s   花时 14s   

2013-06-30 16:53:45 (543 KB/s) - 已保存 “test.rar” [10445121/10445121])

可以看到会从断点的位置(%20)开始下载。
ログイン後にコピー


上記は、ブレークポイント再開をサポートする PHP ファイル ダウンロード クラスの内容です。さらに関連する内容については、注意してください。 PHP 中国語 Web サイト (www.php.cn)!


ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート