2012-07-15 106 views
6

如果我爲zip文件創建鏈接href並點擊鏈接,我的zip文件就會被下載,並打開它獲取我期望的內容。打開下載的壓縮文件創建cpgz文件?

下面是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()代碼做但我已經嘗試了一些基於各種谷歌和其他建議,並沒有工作相關的一些事情。

如果你回答我的問題,很可能你能回答這個問題太:Zipped file with PHP results in cpgz file after extraction

+0

什麼是* cpgz *文件? – hakre 2012-07-15 19:56:10

+0

爲了簡單起見,我把它稱爲cpgz文件,但它實際上是一個'xxx.zip.cpgz'文件。從谷歌,我認爲這是壓縮文件的壓縮。看來我正在下載一個文件,其內容不能被讀取,也許是因爲header()指令已經由'/ canDownload'確定了? – 2012-07-15 19:58:24

+0

嘗試將擴展名更改爲.txt,然後查看您是否有純文本。 – jprofitt 2012-07-15 19:59:49

回答

1

好吧,我回答我自己的問題。

我最初沒有說清楚的主要問題是該文件沒有位於我的應用程序服務器上。它位於亞馬遜AWS s3存儲桶中。這就是爲什麼我在我的問題http://mysite...中使用了完整的url,而不僅僅是服務器上的文件路徑。事實證明,fopen()可以打開網址(所有s3存儲桶「對象」,另一個文件,都有網址),這就是我所做的。

這是我的最終代碼:

$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 
3

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)正在恢復的文件的精確長度。

+0

感謝@cegfault的幫助,我需要使用'http://',因爲zip文件實際上是在遠程服務器上。所以,現在我意識到,readfile()在這種情況下是沒有意義的。有其他建議嗎? – 2012-07-15 20:14:02

+0

你怎麼加載遠程文件?這可能是問題所在。我看到你可能正在使用S3存儲桶。我在Rackspace CloudFiles上遇到了問題,文件也在讀取標題,並且文件中還有一些額外的CRLF(「\ r \ n」)。確保你正確地調用了該文件 - 首先用.txt文件或其他東西來嘗試它。如果您仍然遇到問題,請發佈您的實際S3代碼(刪除用戶名/ apikey/etc),因爲這可能是問題所在。 – cegfault 2012-07-15 20:17:25

+0

hi @cegfault,我目前在我的'/ canDownload' php文件中沒有任何S3代碼。我所擁有的就是你所看到的。我只是在學習S3 SDK。我看到有一個[getObject](http://docs.amazonwebservices.com/AWSSDKforPHP/latest/#m=AmazonS3/get_object)調用,但不知道如何使其適應我的情況。我不是一個完全noob,因爲我可以上傳到我的S3,但仍有點困惑,你可以建議嗎? – 2012-07-15 20:22:23

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"); 
+0

該zip實際上是在S3存儲桶中,而不是我的應用程序。我的問題似乎很複雜,所以我需要包含完整的網址。 – 2012-07-15 20:02:33

5

在我的情況,答案是,有一個空行,在輸出前的ReadFile()。

所以我增加:

ob_end_clean();

readfile($ filename);

但是,您應該搜索代碼中輸出此行的位置。

+0

輝煌,謝謝。 – BarryMode 2017-02-20 23:46:53

+0

完美,謝謝 – SOSTheBlack 2018-03-07 20:09:06

2

另一種可能的答案,我發現很多搜索後,我發現,對於*.zip「解壓縮」到*.zip.cpgz兩個可能的原因是:

  1. *.zip文件已損壞
  2. 的「解壓」正在使用的工具不能 手柄> 2 GB的文件

作爲一個Mac用戶,第二個原因是我的問題,解壓縮文件的原因:標準的Mac OS工具爲存檔實用程序,它顯然不能處理大於2GB的文件。 (這個文件對我來說是一個壓縮的4GB raspbian磁盤映像。)

我最終做的是使用Debian虛擬機,它已經存在於我的Mac上的Virtual Box中。 unzip Debian 8.2上的6.0解壓縮存檔沒有問題。