PHP implements file resumption download

PHP implements file resumption download

code:

<?php
//PHP resumable download
function download($fileurl, $start = 0, $end = '')
{
    $task_sourcefile = '/path/downfile.mp4'; //Locally saved files
        $sourceurl = $fileurl ;  //The remote file to download
        $tokenfile =  'downfile.token';
    $isfileexist =$this->check_remote_file_exists($sourceurl);
    if (!$isfileexist) {
        $isfileexist2 =$this->check_remote_file_exists($sourceurl);
        if (!$isfileexist2) {
            throw new \Exception('The remote file does not exist');
        }
    }
    if (!is_dir(dirname($tokenfile))) {
        mkdir(dirname($tokenfile), 0777, true);
    }
    $sourcefilepath = dirname($task_sourcefile);
  
    if (!is_dir($sourcefilepath)) {
        @mkdir($sourcefilepath, 0777, true);
    }
        
    $ch = curl_init($sourceurl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_USERAGENT, 'SyncTask');
    curl_setopt($ch, CURLOPT_NOSIGNAL, 1); //Note that the timeout must be set to this
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 3600);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 300);
    curl_setopt($ch, CURLOPT_TIMEOUT, 600); //This option is the download timeout period, if the time is set short, if the download is not completed, it will be disconnected, and then resumption of download. If the setting is too long, the download may be stuck for a long time due to network reasons. Please set a reasonable value. It is recommended not to set it too long.
    //curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100 * 1000); //Timeout milliseconds
    curl_setopt($ch, CURLOPT_BUFFERSIZE, 20971520);
    if ($end) {
        curl_setopt($ch, CURLOPT_RANGE, "$start-$end");
    } else {
        curl_setopt($ch, CURLOPT_RANGE, "$start-");
    }
        
    $flag=$tag = 0;

    curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $str) use (&$flag, $task_sourcefile, $end, $sourceurl, $tokenfile, $start, &$tag) {
        $len = strlen($str);
        $flag++;
        if ($flag==1) {
            $httpcode  = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $length  = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
            if ($length ==-1) {
                $tag = 2;
                return false;
            }
            if ($httpcode!=200 && $httpcode!=206) {
                $tag = 2;
                return false;
            }
            if ($start ==0) {
                $data= ['name'=>$sourceurl,'size'=>$length];
                file_put_contents($tokenfile, json_encode($data, JSON_UNESCAPED_UNICODE));
            }
            if ($end) {
                if ($end-$start!=$length) {
                    $tag = 1;
                    return false;
                }
            }
        }
        file_put_contents($task_sourcefile, $str, FILE_APPEND|LOCK_EX);
        return $len;
    });
    $output = curl_exec($ch);
    if ($tag ==2 || $output===false) {
        curl_close($ch);
        clearstatcache();
        download($fileurl, filesize($task_sourcefile), '');
    }
    if ($tag ==1) {
        unlink($task_sourcefile);
        unlink($tokenfile);
        curl_close($ch);
        download($fileurl, 0, '');
        return true;
    }
         
    $tokeninfo  = json_decode(file_get_contents($tokenfile), true);
    $length = $tokeninfo['size'];
    sleep(1);
    clearstatcache();//This is to remove the cache of file information
    if ($length!= filesize($task_sourcefile)) {
        curl_close($ch);
        echo 'Download error: length does not match ~~';
        clearstatcache();
        download($fileurl, filesize($task_sourcefile), '');
    }
    curl_close($ch);
    return true;
}
 
    //run
   $download= download('http://www.test.com/333.mp4');
   var_dump($download);

Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *