简体   繁体   中英

Opening downloaded zip file creates cpgz file?

If I make the url for a zip file the href of a link and click the link, my zip file gets downloaded and opening it gets the contents as I expect.

Here's that HTML:

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

The problem is I'd like the link to point to my application such that I could determine whether the user is authorized to access this zip file.

so I'd like my HTML to be this:

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

and my PHP for the /canDownload page:

//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");
}   

So, I think the problem has to do with the header() code but i've tried a bunch of things related to that based on various google and other SO suggestions and none work.

If you answer my question, it is likely you can answer this question too: Zipped file with PHP results in cpgz file after extraction

The answer in my case was that there was an empty line being output before readfile().

So i added:

ob_end_clean();

readfile($filename);

But you should probably search for the place where this line is being output in your code.

The PHP documentation for readfile says that it will output the contents of a file and return an int.

So your code, echo readfile("$archive"); , will echo $archive (btw, the double quotes are meaningless here; you should remove them), and THEN output the int that is being returned. That is, your line should be: readfile($archive);

Also, you should be using a local path (not an http:// link) to the archive.

Altogether:

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);
}

Lastly, if that does not work, make sure filesize($archive) is returning the accurate length of the file.

Another possible answer, I found After much searching, I found that the two possible reasons for a *.zip "unzipping" to a *.zip.cpgz are:

  1. the *.zip file is corrupted
  2. the "unzip" tool being used can't handle >2GB files

Being a Mac user, the second reason was the cause for my problem unzipping the file: the standard Mac OS tool is Archive Utility , and it apparently can't handle >2GB files. (The file in question for me was a zipped 4GB raspbian disk image.)

What I ended up doing was to use a Debian virtual machine, already existing in Virtual Box on my Mac. unzip 6.0 on Debian 8.2 had no problem unzipping the archive.

You're passing the URL to readfile() like:

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

While you should pass the path on the server, for example:

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

Assuming the file is located in the upload folder.

Additionally try the following headers:

header("Content-type: application/octet-stream"); 
header("Content-disposition: attachment; filename=file.zip");  

Ok, I answered my own question.

The main problem, which I originally didn't make clear, was that the file was not located on my application server. It was in a Amazon AWS s3 bucket. That is why I had used a full url in my question, http://mysite... and not just a file path on the server. As it turns out fopen() can open urls (all s3 bucket "objects", aka files, have urls) so that is what I did.

Here's my final code:

$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

在我的情况下,我试图在public_html上面的目录中创建文件,并且托管的规则不允许它。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM