PHP code for downloading a ZIP

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
tarview
Forum Newbie
Posts: 4
Joined: Mon Oct 29, 2007 7:44 am

PHP code for downloading a ZIP

Post by tarview »

Well, last time I had an issue and posted here, it fixed itself, so maybe it'll happen again.

I'm trying to add code to let the visitor download a ZIP file, then show some HTML follow-up. Here's what I'm trying:

Code: Select all

<?php
...
header( "Content-type: application/x-zip-compressed" );
header( "Content-Disposition: attachment; filename='example.zip'" );
readfile( "source.zip" );
?>
<html>
...
</html>
Now, I realize that it's recommended (maybe required?) to put in "Content-length", but then I can't add the HTML (unless I add the length of the HTML to content-length, maybe). But that's not the issue.

Instead of downloading the ZIP, it displays the contents in raw text form. This happens whether or not I include Content-length. The only difference then is whether it shows the follow-up HTML.

I've tried other MIME types, too, including
applicaton/zip
multipart/zip
application/octet-stream

All give the same result. I've even tried excluding the Content-type header altogether to see if PHP could figure it out.

Is there maybe a server setting that I'm not aware of? My gut tells me it has to do with either the MIME type or readfile. If so, what's the alternative?

This is a hosted account, so I don't have root access. Also, it's PHP4.

(Just refreshed and still not working. Maybe after I hit submit...)
User avatar
JAM
DevNet Resident
Posts: 2101
Joined: Fri Aug 08, 2003 6:53 pm
Location: Sweden
Contact:

Re: PHP code for downloading a ZIP

Post by JAM »

You cant show html (or code) after the download is triggered. The download must then be called upon using javascript, ajax (same thing basicly) or by using iframes or similiar solutions.

Other than that, here are some ideas for headers to use (for a rar file, but still):

Code: Select all

    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header("Content-Type: application/x-rar-compressed");
    header("Content-Disposition: attachment; filename=foo.rar;");
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: ".filesize("foo.rar"));
    @readfile("foo.rar");
tarview
Forum Newbie
Posts: 4
Joined: Mon Oct 29, 2007 7:44 am

Re: PHP code for downloading a ZIP

Post by tarview »

Thank you! I can live without the HTML follow-up (sent the info in an e-mail), so this works out fine. 8)
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: PHP code for downloading a ZIP

Post by John Cartwright »

JAM wrote:You cant show html (or code) after the download is triggered. The download must then be called upon using javascript, ajax (same thing basicly) or by using iframes or similiar solutions.

Other than that, here are some ideas for headers to use (for a rar file, but still):

Code: Select all

    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header("Content-Type: application/x-rar-compressed");
    header("Content-Disposition: attachment; filename=foo.rar;");
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: ".filesize("foo.rar"));
    @readfile("foo.rar");
I believe the filename attribute in the content disposition header is required to be quoted.

Code: Select all

   header("Content-Disposition: attachment; filename=\"foo.rar;\"");
User avatar
JAM
DevNet Resident
Posts: 2101
Joined: Fri Aug 08, 2003 6:53 pm
Location: Sweden
Contact:

Re: PHP code for downloading a ZIP

Post by JAM »

Good catch, missed that one. :teach:
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: PHP code for downloading a ZIP

Post by Chris Corbyn »

Jcart wrote:I believe the filename attribute in the content disposition header is required to be quoted.

Code: Select all

   header("Content-Disposition: attachment; filename=\"foo.rar;\"");
Actually it's not ;) It's required to be a valid "phrase" but if it hasn't got any spaces (or special characters) in it then it doesn't need the quotes ;)

PS: Move the semi-colon in your code outside of the double quotes...
User avatar
JAM
DevNet Resident
Posts: 2101
Joined: Fri Aug 08, 2003 6:53 pm
Location: Sweden
Contact:

Re: PHP code for downloading a ZIP

Post by JAM »

Chris Corbyn wrote:Actually it's not ;) It's required to be a valid "phrase" but if it hasn't got any spaces (or special characters) in it then it doesn't need the quotes ;)

PS: Move the semi-colon in your code outside of the double quotes...
Actually II, according to the rfc (1806 and 2616) it should. :D
filename-parm = "filename" "=" quoted-string
It seldom breaks so noone really tend to care. not even part of the http/1.1 standards.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: PHP code for downloading a ZIP

Post by Chris Corbyn »

JAM wrote:
Chris Corbyn wrote:Actually it's not ;) It's required to be a valid "phrase" but if it hasn't got any spaces (or special characters) in it then it doesn't need the quotes ;)

PS: Move the semi-colon in your code outside of the double quotes...
Actually II, according to the rfc (1806 and 2616) it should. :D
filename-parm = "filename" "=" quoted-string
It seldom breaks so noone really tend to care. not even part of the http/1.1 standards.
I concede :oops: I assumed the MIME implementation would match that of RFC 2045's Content-Disposition spec.

EDIT | Or whichever RFC that header is defined in for mail. Grrr... too many dman RFC's :P

Here's RFC 2045's definition of a parameter:

Code: Select all

parameter := attribute "=" value
 
     attribute := token
                  ; Matching of attributes
                  ; is ALWAYS case-insensitive.
 
     value := token / quoted-string
 
     token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
                 or tspecials>
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: PHP code for downloading a ZIP

Post by Chris Corbyn »

Ah, so RFC 1806 is what I was thinking of correctly, but RFC 2616 ammends that syntax for HTTP for some reason. I wonder why that is.

EDIT | I'll let it drop swear :P Just checking RFC 2183, which replaces 1806 and the syntax for the value remained the same there too. Ok, I'm done, but confused :lol:
Post Reply