Skip to content
Advertisement

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.

Advertisement

Answer

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);
}
?>
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement