【问题标题】:curl get remote file and force download at same timecurl 获取远程文件并同时强制下载
【发布时间】:2020-12-07 04:58:31
【问题描述】:

我正在尝试获取远程文件并同时将其强制下载给用户。 无法粘贴代码,代码太长。但是 curl 功能可以工作,但问题是它不会输出任何内容,直到它首先获取远程文件然后强制将其下载给用户。

我用它来告诉 curl 返回一个回调

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

现在在我的 readCallback 函数中我这样做:

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

但它不会返回任何内容,它只是等待获取远程文件完成。

【问题讨论】:

标签: php curl


【解决方案1】:

试试这个,它将使用 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);
}
?>

【讨论】:

  • 为了获得更好的性能考虑在未来使用readfile 和 PHP 流上下文。你会喜欢的。
  • 正在谈论远程文件,我很乐意看到你的意思的一个例子,因为我已经花了一个小时试图解决这个问题。 :)
  • readfile 适用于 PHP 流,例如你可以让它获取远程文件。如果可以直接流式传输到 PHP 输出(我认为这也是可能的),流复制流也可能值得研究。但是我认为 readfile 还是有点轻。 php.net/manual/en/book.stream.php ; php.net/manual/en/stream.contexts.php 最后:ua2.php.net/manual/en/function.readfile.php
  • 有机会添加 http_auth 吗?我做到了,现在我的 curl 不工作 curl_setopt($ch, CURLOPT_USERPWD, 'u:p'); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
  • @LawrenceCherone 为什么在客户端将下载速度限制在几kbps?
【解决方案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.

【讨论】:

  • 但这不是等到文件通过 curl 完成下载然后输出吗?
  • 是的,但这是负面的吗?传输应该非常快,因为这是从一台服务器到另一台服务器的传输,并且可能比您的客户端连接快得多。您可以在本地缓存这些文件,以便下一个请求相同文件的用户将获得更快的响应。两种方法下载时间的差异你测过吗?
  • 好吧,我想在将它们呈现给用户时缓存它们,当我自己将其下载到服务器时,我让用户在另一端下载它,当我下载它时,我可以自己缓存它,然后用户速度不能超过服务器,即使是我可以限制它。
【解决方案3】:

如何获取 (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() 函数会分块读取流,并将其打印到输出,因此不会占用太多内存...

【讨论】:

    猜你喜欢
    • 2010-12-03
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多