Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
235 views
in Technique[技术] by (71.8m points)

php - curl get remote file and force download at same time

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 is it doesn't out put anything till it gets the remote file first then it force downloads it to user.

I use this to tell curl to return a callback

curl_setopt($ch, CURLOPT_READFUNCTION, 'readCallback');

now in my readCallback function I do this :

function readCallback($curl, $stream, $maxRead){
    $read = fgets($stream, $maxRead);
    echo $read;
    return $read;
}

but it doesn't return anything it just waits till fetching remote file is finished.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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);
}
?>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...