打开下载的zip文件会创建cpgz文件吗?

时间:2012-07-15 19:52:30

标签: php http-headers zip zipfile

如果我为一个zip文件的url创建一个链接的href并点击该链接,我的zip文件会被下载并打开它获取我期望的内容。

这是HTML:

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

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

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

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

/canDownload页面的PHP:

//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 extraction

6 个答案:

答案 0 :(得分:11)

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

所以我补充道:

  

ob_end_clean();

     

的ReadFile($文件名);

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

答案 1 :(得分: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)返回文件的准确长度。

答案 2 :(得分:2)

另一个可能的答案,我发现经过多次搜索,我发现了*.zip&#34;解压缩&#34;的两个可能原因。到*.zip.cpgz是:

  1. *.zip文件已损坏
  2. &#34;解压&#34;使用的工具不能 处理&gt; 2GB文件
  3. 作为Mac用户,第二个原因导致我的问题解压缩文件:标准的Mac OS工具是 Archive Utility ,它显然无法处理&gt; 2GB文件。 (有问题的文件是压缩的4GB raspbian磁盘映像。)

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

答案 3 :(得分:1)

您将网址传递给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");  

答案 4 :(得分:1)

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

我最初没有说清楚的主要问题是该文件不在我的应用程序服务器上。它是在亚马逊AWS s3桶中。这就是为什么我在我的问题http://mysite...中使用了一个完整的URL,而不仅仅是服务器上的文件路径。事实证明fopen()可以打开网址(所有s3桶“对象”,a.k.a。文件,有网址),这就是我所做的。

这是我的最终代码:

$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

答案 5 :(得分:0)

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