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.
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);
}
?>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With