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
You're passing the URL to
readfile()
like:While you should pass the path on the server, for example:
Assuming the file is located in the upload folder.
Additionally try the following headers:
Another possible answer, I found After much searching, I found that the two possible reasons for a
*.zip
"unzipping" to a*.zip.cpgz
are:*.zip
file is corruptedBeing 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.In my case, I was trying to create the file in a directory above public_html and the rules of the hosting didn't allow it.
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 outfopen()
can open urls (all s3 bucket "objects", a.k.a. files, have urls) so that is what I did.Here's my final code:
The answer in my case was that there was an empty line being output before readfile().
So i added:
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 theint
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:
Lastly, if that does not work, make sure
filesize($archive)
is returning the accurate length of the file.