View Full Version : dynamically creating .zip file on a windows server

01-08-2004, 08:49 PM

i'm writing an application that allows a user to pick files to download from a list. i need a way to bring all those files together and compress them into one .zip file on a windows server.

i've gotten it to work on a linux server by simply using the exec() function to run zip on the command line, and then use header() to get the browser to download the resulting file.

so, what i'd really like to do is learn how to use PHP instead of the command line to create a temporary zip file. in other words, a cross platform solution. perhaps i need to use zlib? can zlib be used to create a .zip, instead of a .gz?

thanks in advance!

01-08-2004, 08:58 PM
excellent question. I'd start by looking into this:

Make sure you read the comments.

01-08-2004, 09:12 PM
cool! i'd looked at that page a few times already, but never bothered to scroll all the way down. the last comment on the page (default view, newest first) talks about using zip.lib.php from phpMyAdmin, which i had already installed on my server.

so, i'm cannibalizing bits from export.php in phpMyAdmin to use zip.lib.php.

i'll report how it goes.

01-08-2004, 09:25 PM
good deal. Please do! I'd love to not reinvent the wheel should I want to perfrom some similar action!

01-08-2004, 09:36 PM
ok, next question:

i'm looking at the function addFile() in the zip.lib.php library, and it looks like it wants raw data from each file... right now, all i have is an array with a bunch of file paths. what's the best way to loop through and get the raw data from each file, put it in the zipFile, and so on? seems like that would be a lot of overhead... the files i'm talking about are mostly MS Word docs, and pdfs.

what do you think?

01-08-2004, 10:58 PM

First, Check out http://www.phpconcept.net/pclzip/index.en.php#fonctions

Then... I guess...
looks like you'd:

$myzip = <insert code here to create the new zip file, like = new Zip or whatever>

array = array("files\file1.doc","files\file2.doc","pdfs\mypdf.pdf");

foreach ($array as $filename) {
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));

I guess? i can't think of an easier way...

01-08-2004, 11:11 PM
yeah, that's what i came up with too.

include 'zip.lib.php';


$zipFile = new zipfile();
foreach($files as $path)
$fh = fopen($path, "rb");
$data = fread($fh, filesize($path));
$zipFile -> addFile($data, $path);

with $files being an array full of paths. (i.e. "files/thisisafile.doc")

now, the problem seems to be that the .zip file isn't getting the proper headers or something... here's my code for that:

$mdate=gmdate("D, d M Y H:i:s T");

$user_agent = strtolower ($_SERVER["HTTP_USER_AGENT"]);
if ((is_integer (strpos($user_agent, "msie"))) && (is_integer (strpos($user_agent,"win"))))
header( "Content-Disposition: filename=\"$zipFileName\"");
header( "Content-Disposition: attachment; filename=\"$zipFileName\"");
header("Last-Modified: $mdate");
header("Content-Type: application/zip");

//print out the entire zip file for download
echo $zipFile -> file();

should there be some kindof footer or something? that (echo $zipFile...) is the last line in the program. i'm not getting an error, just a messed up .zip file.

any ideas?

01-08-2004, 11:14 PM
oh, and does anybody know a good way to give the user some kindof "Don't give up, there IS something downloading" page, even after the headers are sent? like, a redirect() function? thanks!

01-08-2004, 11:36 PM
regarding the messed up zip file....

not all ZIPs are created equal. What application are you opening the zips with? Winzip? PKUnzip? ZipCentral? EasyZip? ZipGhost..... the list goes on...

I've learned that not all apps open all zips, due to minor discrepancies.

The header information looks correct to me. Although this page (http://www.zend.com/zend/spotlight/creating-zip-files2.php) (custom class), seems to indicate that crc information, null values, etc need to be placed into the header as well.

As for the wait message, how long does it take (average)?

01-08-2004, 11:47 PM
the whole thing seems to work fine when downloading on a windows machine. (XP) it doesn't work quite right on my Mac. on windows, i'm using whatever the built-in wizard is to uncompress and read the zip. on mac, it's the unzipper that comes with OS X 10.3. (i think it's just using the gunzip utility from unix)

so, should i be satisfied that it works on windows? or is the fact that it doesn't work on Mac a sign that something more sinister is at work? the application is mainly going to be run on windows, so it shouldn't ever matter... so this is probably a problem to solve later.

however, the time issue... depending on the size of the files chosen, and how many are chosen, it takes from next to no time to maybe 30 or 40 seconds. this would be the time while the server is buffering all those files and compressing them into the .zip file.

here's the problem, though. right now, i have the zipfile being buffered directly into a file that the browser is downloading. so what i actually need to do is redirect to a "please wait" page BEFORE i start buffering all them thar files... so how do i do that?

01-09-2004, 06:01 AM
One solution would be to point them to a php page that does something like:

print out "You're now downloading blah blah blah. Please wait while your download completes...."

insert (at the top) an <HTTP-EQUIV="Refresh" CONTENT="30; URL="<?php the_new_zip_file.zip ?>">

of course, that way they wait 30 seconds...then are redirected...if it takes longer...

You could send them to a page that says, please wait while your file is being created.... then, insert the php code to generate the file....when it's done executing, it'll continue with the script...which could then generate a link directly to the file (requiring 2 clicks, which stinks...)

I'm thinking there is a way, using a JavaScript pop-up window, but it just isn't coming to me.... you COULD....

Let's say the link is:
<a href="the_zip_file.zip">

well set it up so that it pops up javascript window with the please wait message. Also popup a window to generate the file.... then close the window when done, and redirect popup2 to the file.... or...
sheesh. I'm sure there is an easier way....

01-09-2004, 06:16 AM
send them to a page that says, please wait while your file is being created.... then, insert the php code to generate the file....when it's done executing, it'll continue with the script...which could then generate a link directly to the file (requiring 2 clicks, which stinks...)

that's pretty much what i'm trying to do now, except for some reason, instead of displaying the "please wait..." and then doing the compression, and then writing out "click here to download", it waits until the whole page is done, compression and all, and then puts up "please wait... click here". how do i force it to display what's ready? i know i've seen websites that do this kind of thing... i just can't think of any to go steal it from. ;) (not that i'd be able to look at their PHP or Perl or whatever, but maybe it would help anyway)

the javascript idea sounds feasible... but also a little "over the top", perhaps. i'd like to keep it straight HTML (generated by PHP of course) if possible. nice way to think outside the box, though! :thumbsup: (sorry, i couldn't resist)

01-09-2004, 06:38 AM

I dunno if you can use that to force it to print...buffer...then execute again...I dunno...

01-09-2004, 05:01 PM
looks like that's more useful if you have the opposite problem i have. in otherwords, if i wanted it to wait longer to echo... oh well.

i think for now, i'm not going to worry a whole lot about a "please wait" message. or rather, i think i'll put one next to the submit button. that way, it's one click, but if they don't wait long enough it's their own fault. :)

thanks for all your help!!

01-09-2004, 05:44 PM
lol. excellent solution. ;) hehe.

And you're most welcome. :thumbsup: