9

如果我将 zip 文件的 urlhref设为链接的链接并单击该链接,我的 zip 文件将被下载并打开它会得到我期望的内容。

这是 HTML:

<a href="http://mysite.com/uploads/my-archive.zip">download zip</a>

问题是我希望链接指向我的应用程序,以便我可以确定用户是否有权访问此 zip 文件。

所以我希望我的 HTML 是这样的:

 <a href="/canDownload">download zip</a> 

和我的页面PHP /canDownload

//business logic to determine if user can download

if($yesCanDownload){

$archive='https://mysite.com/uploads/my-archive.zip';
header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename=".basename($archive));
header("Content-Length: ".filesize($archive));
ob_clean();
flush();
echo readfile("$archive");
}   

所以,我认为问题与header()代码有关,但我已经根据各种谷歌和其他 SO 建议尝试了一堆与此相关的事情,但没有任何工作。

如果您回答我的问题,您很可能也可以回答这个问题:Zipped file with PHP results in cpgz file after extract

4

6 回答 6

13

就我而言,答案是在 readfile() 之前输出了一个空行。

所以我补充说:

ob_end_clean();

读取文件($文件名);

但是您可能应该在代码中搜索此行的输出位置。

于 2013-09-11T14:16:52.287 回答
4

readfile的 PHP 文档说它将输出文件的内容并返回一个 int。

因此,您的代码echo readfile("$archive");将回$archive显(顺便说一句,双引号在这里毫无意义;您应该删除它们),然后输出int正在返回的内容。也就是说,您的行应该是:readfile($archive);

此外,您应该使用存档的本地路径(不是 http:// 链接)。

共:

if($yesCanDownload){
    $archive='/path/to/my-archive.zip';
    header("Content-Type: application/zip");
    header("Content-Disposition: attachment; filename=".basename($archive));
    header("Content-Length: ".filesize($archive));
    ob_clean();
    flush();
    readfile($archive);
}

最后,如果这不起作用,请确保filesize($archive)返回文件的准确长度。

于 2012-07-15T20:00:33.237 回答
2

好的,我回答了我自己的问题。

我最初并没有说清楚的主要问题是该文件不在我的应用程序服务器上。它位于 Amazon AWS s3 存储桶中。这就是为什么我在我的问题中使用了完整的 url,http://mysite...而不仅仅是服务器上的文件路径。事实证明fopen()可以打开 url(所有 s3 存储桶“对象”,也就是文件,都有 url),这就是我所做的。

这是我的最终代码:

$zip= "http://mysite.com/uploads/my-archive.zip"; // my Amazon AWS s3 url
header("Content-Type: archive/zip"); // works with "application/zip" too
header("Content-Disposition: attachment; filename='my-archive.zip"); // what you want to call the downloaded zip file, can be different from what is in the s3 bucket   
$zip = fopen($zip,"r"); // open the zip file
echo fpassthru($zip); // deliver the zip file
exit(); //non-essential
于 2012-07-15T21:02:27.440 回答
2

另一个可能的答案,我发现经过大量搜索后,我发现*.zip“解压缩”到 a的两个可能原因*.zip.cpgz是:

  1. 文件已*.zip损坏
  2. 正在使用的“解压缩”工具无法处理 >2GB 的文件

作为 Mac 用户,第二个原因是我解压缩文件时出现问题的原因:标准的 Mac OS 工具是Archive Utility,它显然无法处理 >2GB 的文件。(对我来说,有问题的文件是一个压缩的 4GB raspbian磁盘映像。)

我最终做的是使用一个 Debian 虚拟机,它已经存在于我的 Mac 上的 Virtual Box 中。unzipDebian 8.2 上的 6.0 解压缩档案没有问题。

于 2015-09-30T23:01:46.400 回答
1

您将 URL 传递给readfile()喜欢:

$archive = 'https://mysite.com/uploads/my-archive.zip';

虽然您应该传递服务器上的路径,例如:

$archive = '/uploads/my-archive.zip';

假设文件位于上传文件夹中。

另外尝试以下标题:

header("Content-type: application/octet-stream"); 
header("Content-disposition: attachment; filename=file.zip");  
于 2012-07-15T20:01:10.607 回答
0

就我而言,我试图在 public_html 上方的目录中创建文件,但托管规则不允许这样做。

于 2018-07-21T12:10:24.357 回答