我用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等远程服务器上时(我当然拥有权利),我该如何处理?
我不喜欢任何重定向,因为用户不应该看到原始位置。
我是否必须下载文件并将其临时(临时)存储在服务器上?
答案 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是最好的。除此之外,前两个是最有可能需要的,但如果您愿意,我可以为其他代码填写一些示例代码:)