curl get remote file and force download at same time

前端 未结 3 2083
刺人心
刺人心 2020-12-13 22:53

I\'m trying to get a remote file and force download it to user at the same time. I can\'t paste the code ,the code is too long . but the curl function works ,but the problem

相关标签:
3条回答
  • 2020-12-13 23:32

    how to get big (8GB) remote file and force download at same time, while not killing you server:

    <?php
    
    $url = 'http://www.example.com/bigfile.mp4';
    
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($url).'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    
    readfile($url);
    

    the readfile() function will read the stream in chunks, and print it to the output, so it will not use much memory...

    0 讨论(0)
  • 2020-12-13 23:38

    Try this, it will use curl to get the total size of the file then download partial chunks of the file proxying it to the user so as there is no wait for curl to download it first, I tested this with an avi,mp4,mp3 and an exe, hope it helps:

    <?php
    $file = 'http://example.com/somefile.mp3';
    download($file,2000);
    
    /*
    Set Headers
    Get total size of file
    Then loop through the total size incrementing a chunck size
    */
    function download($file,$chunks){
        set_time_limit(0);
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-disposition: attachment; filename='.basename($file));
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Expires: 0');
        header('Pragma: public');
        $size = get_size($file);
        header('Content-Length: '.$size);
    
        $i = 0;
        while($i<=$size){
            //Output the chunk
            get_chunk($file,(($i==0)?$i:$i+1),((($i+$chunks)>$size)?$size:$i+$chunks));
            $i = ($i+$chunks);
        }
    
    }
    
    //Callback function for CURLOPT_WRITEFUNCTION, This is what prints the chunk
    function chunk($ch, $str) {
        print($str);
        return strlen($str);
    }
    
    //Function to get a range of bytes from the remote file
    function get_chunk($file,$start,$end){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $file);
        curl_setopt($ch, CURLOPT_RANGE, $start.'-'.$end);
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
        curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'chunk');
        $result = curl_exec($ch);
        curl_close($ch);
    }
    
    //Get total size of file
    function get_size($url){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_NOBODY, true);
        curl_exec($ch);
        $size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
        return intval($size);
    }
    ?>
    
    0 讨论(0)
  • 2020-12-13 23:40

    Try using curl like this:

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_HTTPGET, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    $result = curl_exec($ch);
    
    $msg = new HttpMessage($result);
    return $msg->getBody();
    

    The return value then is the content of the requested file, which you can then output. So no need for a callback. HTTPMessage docs.

    0 讨论(0)
提交回复
热议问题