提供要下载的远程文件

时间:2014-02-19 17:31:05

标签: php

我用PHP提供了一个zip文件下载:

header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header('Content-Description: File Transfer');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: '.filesize($location));

readfile($location);

当文件位于S3或Dropbox等远程服务器上时(我当然拥有权利),我该如何处理?

我不喜欢任何重定向,因为用户不应该看到原始位置。

我是否必须下载文件并将其临时(临时)存储在服务器上?

1 个答案:

答案 0 :(得分:2)

您可以(并且可能 !)在本地存储文件,但您

所以这里有一些可能的解决方案。这些示例假设$ filename已安全生成或已使用以下内容进行清理:

$filename = preg_replace('/[^\w.]/', '', $filename); //sanitize

1)readfile,启用allow_url_fopen: (有关详细信息,请参阅http://www.php.net/manual/en/features.remote-files.php

readfile("http://url/to/your/$filename");

2)更加缓慢的东西,比如:

// Serve a file from a remote server.
function serveFile($filename) {
    // Folder to locally cache files. Ensure your php user has write access.
    $cacheFolder = '/path/to/some/cache/folder';
    // URL to the folder you'll be downloading from.
    $remoteHost = 'http://remote.host/path/to/folder/';

    $cachedFile = "$cacheFolder$filename";

    // Cache the file if we haven't already.
    if (!file_exists($cachedFile)) {
        // May want to test these two calls, and log failures.
        file_put_contents($cachedFile, file_get_contents("$remoteHost$filename"));
    }
    else {
        // Set the last accessed time.
        touch($cachedFile);
    }
    readfile($cachedFile) or die ("Well, shoot");

    // Optionally, clear old files from the cache.
    clearOldFiles($cacheFolder);
}

// Clear old files from cache folder, based on last mtime.
// Could also clear depending on space used, etc.
function clearOldFiles($cacheFolder) {
    $maxTime = 60 * 60 * 24; // 1 day: use whatever works best.
    if ($handle = opendir($cacheFolder)) {
        while (false !== ($file = readdir($handle))) {
           if ((time() - filemtime($path.$file)) > $maxTime) {
               unlink($path.$file);
          }
       }
   }
}

3)如果您无权启用allow_url_fopen,请使用CURL。

4)如果您没有安装CURL并且无法安装,请使用像wget这样的外部程序。

5)最坏的情况:在远程服务器上打开一个到端口80的套接字,然后只发送该文件的HTTP请求。

6)您的网络服务器可能能够进行某种代理重定向,这意味着您实际上并不需要任何代码来完成此任务,您可以免费获得缓存和其他优化。例如,请参阅有关Apache的mod_proxy的文档:https://httpd.apache.org/docs/2.2/mod/mod_proxy.html

如果你可以的话,选项6是最好的。除此之外,前两个是最有可能需要的,但如果您愿意,我可以为其他代码填写一些示例代码:)