我正在尝试获取远程文件并强制同时将其下载到用户。 我无法粘贴代码,代码太长。但curl函数有效,但问题是它没有输出任何东西,直到它首先获取远程文件然后它强制下载到用户。
我用它告诉curl返回一个回调
curl_setopt($ch, CURLOPT_READFUNCTION, 'readCallback');
现在在我的readCallback函数中我这样做:
function readCallback($curl, $stream, $maxRead){
$read = fgets($stream, $maxRead);
echo $read;
return $read;
}
但它不会返回任何它等待直到获取远程文件完成的任何内容。
答案 0 :(得分:6)
试试这个,它会使用curl来获取文件的总大小,然后将代理它的文件的部分块下载到用户,这样就没有等待 curl首先下载它,我用avi,mp4,mp3和exe测试了这个,希望它有所帮助:
<?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);
}
?>
答案 1 :(得分:2)
尝试使用curl:
$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();
然后返回值是所请求文件的内容,然后可以输出。所以不需要回调。 HTTPMessage docs
答案 2 :(得分:0)
如何获取大(8GB)远程文件并同时强制下载,同时又不杀死服务器:
<?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);
readfile()函数将分块读取流并将其打印到输出,因此不会占用太多内存...