PHP curl 直接下载/流式传输部分内容


PHP Curl direct Download/Stream Partial Content

我想将文件从其他网站/网站直接发送给用户,而无需将文件存储在我的服务器上。文件是存档约100MB到1GB

使用一个线程下载工作正常。这是我的代码:

$ch5 = curl_init();
if (isset($_SERVER['HTTP_RANGE'])) {
    //http://stackoverflow.com/questions/157318/resumable-downloads-when-using-php-to-send-the-file
    preg_match('/bytes=('d+)-('d+)?/', $_SERVER['HTTP_RANGE'], $matches);
    $offset = intval($matches[1]);
    $end = $matches[2] || $matches[2] === '0' ? intval($matches[2]) : $size - 1;
    curl_setopt($ch5, CURLOPT_RANGE, "$offset-$end");
}
curl_setopt($ch5, CURLOPT_URL, $direct_link);
curl_setopt($ch5, CURLOPT_TIMEOUT, 3550); 
curl_setopt($ch5, CURLOPT_CONNECTTIMEOUT, 15); 
curl_setopt($ch5, CURLOPT_HEADERFUNCTION, 'readHeader');
curl_exec($ch5);
$dlsize = curl_getinfo($ch5,CURLINFO_SIZE_DOWNLOAD );
$time = curl_getinfo($ch5,CURLINFO_TOTAL_TIME);
curl_close($ch5);
function readHeader($ch, $header) // Send header from the Downloaded file to the User
{
    header($header);
    return strlen($header);
}

问题是,如果请求包含类似"范围:bytes=0-"的范围,PHP 会下载完整的文件并将其发送给用户。但是用户下载速度要慢得多(导致下载速度变慢),然后将其下载到我的服务器,但如果文件已完全下载,则该文件在外部服务器上不可用。当客户端发出后半部分的范围请求或其他内容时,请求将转到外部服务器并且文件不可用,因为它已经被第一个请求完全下载,但我无法访问数据或有没有办法获取这些数据,而无需将它们保存在我的磁盘上?

我想节省带宽,并希望为用户提供发出范围请求的可能性。因此,PHP 应该只下载用户真正想要下载的数量,或者在外部服务器和用户之间建立直接连接。

实际上我在Ubuntu 12.04.5上使用nginx/1.6.2和PHP 5.5.20-1

我通过将nginx与X-Sendfile/X-Accel-Redirect一起使用来解决我的问题。更多信息请见:wiki.nginx.org/XSendfile