PHP远程文件流与恢复支持
发布时间:2020-07-23 04:29:37  所属栏目:PHP  来源:互联网 
            导读:首先,我知道以前有类似的问题. 这个问题几乎解释了这个问题,但是, 该文件托管在另一台服务器上,用户将通过我的脚本下载文件,流式传输给他… 但是问题是用户无法恢复一次暂停…任何解决方案? 您可以尝试使用Accept-Ranges和Content-Range实现自己的下载脚本,
                
                
                
            | 
                         首先,我知道以前有类似的问题. 这个问题几乎解释了这个问题,但是, 该文件托管在另一台服务器上,用户将通过我的脚本下载文件,流式传输给他… 但是问题是用户无法恢复一次暂停…任何解决方案? 您可以尝试使用Accept-Ranges和Content-Range实现自己的下载脚本,这里是一个概念:set_time_limit(0);
$download = new ResumeDownload("word.dir.txt",50000); //delay about in microsecs 
$download->process(); 
 使用Internet下载管理器 开始 已暂停 暂停状态 恢复 成品 使用类 class ResumeDownload {
    private $file;
    private $name;
    private $boundary;
    private $delay = 0;
    private $size = 0;
    function __construct($file,$delay = 0) {
        if (! is_file($file)) {
            header("HTTP/1.1 400 Invalid Request");
            die("<h3>File Not Found</h3>");
        }
        $this->size = filesize($file);
        $this->file = fopen($file,"r");
        $this->boundary = md5($file);
        $this->delay = $delay;
        $this->name = basename($file);
    }
    public function process() {
        $ranges = NULL;
        $t = 0;
        if ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_SERVER['HTTP_RANGE']) && $range = stristr(trim($_SERVER['HTTP_RANGE']),'bytes=')) {
            $range = substr($range,6);
            $ranges = explode(',',$range);
            $t = count($ranges);
        }
        header("Accept-Ranges: bytes");
        header("Content-Type: application/octet-stream");
        header("Content-Transfer-Encoding: binary");
        header(sprintf('Content-Disposition: attachment; filename="%s"',$this->name));
        if ($t > 0) {
            header("HTTP/1.1 206 Partial content");
            $t === 1 ? $this->pushSingle($range) : $this->pushMulti($ranges);
        } else {
            header("Content-Length: " . $this->size);
            $this->readFile();
        }
        flush();
    }
    private function pushSingle($range) {
        $start = $end = 0;
        $this->getRange($range,$start,$end);
        header("Content-Length: " . ($end - $start + 1));
        header(sprintf("Content-Range: bytes %d-%d/%d",$end,$this->size));
        fseek($this->file,$start);
        $this->readBuffer($end - $start + 1);
        $this->readFile();
    }
    private function pushMulti($ranges) {
        $length = $start = $end = 0;
        $output = "";
        $tl = "Content-type: application/octet-streamrn";
        $formatRange = "Content-range: bytes %d-%d/%drnrn";
        foreach ( $ranges as $range ) {
            $this->getRange($range,$end);
            $length += strlen("rn--$this->boundaryrn");
            $length += strlen($tl);
            $length += strlen(sprintf($formatRange,$this->size));
            $length += $end - $start + 1;
        }
        $length += strlen("rn--$this->boundary--rn");
        header("Content-Length: $length");
        header("Content-Type: multipart/x-byteranges; boundary=$this->boundary");
        foreach ( $ranges as $range ) {
            $this->getRange($range,$end);
            echo "rn--$this->boundaryrn";
            echo $tl;
            echo sprintf($formatRange,$this->size);
            fseek($this->file,$start);
            $this->readBuffer($end - $start + 1);
        }
        echo "rn--$this->boundary--rn";
    }
    private function getRange($range,&$start,&$end) {
        list($start,$end) = explode('-',$range);
        $fileSize = $this->size;
        if ($start == '') {
            $tmp = $end;
            $end = $fileSize - 1;
            $start = $fileSize - $tmp;
            if ($start < 0)
                $start = 0;
        } else {
            if ($end == '' || $end > $fileSize - 1)
                $end = $fileSize - 1;
        }
        if ($start > $end) {
            header("Status: 416 Requested range not satisfiable");
            header("Content-Range: */" . $fileSize);
            exit();
        }
        return array(
                $start,$end
        );
    }
    private function readFile() {
        while ( ! feof($this->file) ) {
            echo fgets($this->file);
            flush();
            usleep($this->delay);
        }
    }
    private function readBuffer($bytes,$size = 1024) {
        $bytesLeft = $bytes;
        while ( $bytesLeft > 0 && ! feof($this->file) ) {
            $bytesLeft > $size ? $bytesRead = $size : $bytesRead = $bytesLeft;
            $bytesLeft -= $bytesRead;
            echo fread($this->file,$bytesRead);
            flush();
            usleep($this->delay);
        }
    }
} 
 File Used (编辑:莱芜站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!  | 
                  
