|
|
Terms of Agreement:
By using this article, you agree to the following terms...
1) You may use
this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
2) You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this article from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the article or article's description. | Ever wondered how you could create ZIP files on the
fly? In this article, which I found on Zend.com, you'll be able to. The original version can be found here: http://www.zend.com/zend/spotlight/creating-zip-files2.php
<?php
/*
Zip file creation class
makes zip files on the fly...
use the functions add_dir() and add_file() to build the zip file;
see example code below
by Eric Mueller
http://www.themepark.com
v1.1 9-20-01
- added comments to example
v1.0 2-5-01
initial version with:
- class appearance
- add_file() and file()
methods
- gzcompress()
output hacking
by Denis O.Philippov, webmaster@atlant.ru, http://www.atlant.ru
*/
// official ZIP file format: http://www.
// pkware.com/appnote.txt
class zipfile
{
var $datasec =
array(); // array to store compressed data
var $ctrl_dir
= array(); // central
directory
var $eof_ctrl_dir
= "\x50\x4b\x05\x06\x00\x00\x00\x00";
//end of Central directory record
var $old_offset
= 0;
function add_dir($name)
// adds
"directory" to archive - do this before putting any files in
directory!
// $name - name of directory... like this:
"path/"
// ...then you can add files using add_file with names
like "path/file.txt"
{
$name
= str_replace("\\",
"/", $name);
$fr
= "\x50\x4b\x03\x04";
$fr
.= "\x0a\x00"; //
ver needed to extract
$fr
.= "\x00\x00"; //
gen purpose bit flag
$fr
.= "\x00\x00"; //
compression method
$fr
.= "\x00\x00\x00\x00";
// last mod time and date
$fr
.= pack("V",0);
// crc32
$fr
.= pack("V",0);
//compressed filesize
$fr
.= pack("V",0);
//uncompressed filesize
$fr
.= pack("v",
strlen($name)
); //length of pathname
$fr
.= pack("v",
0 ); //extra
field length
$fr
.= $name;
//
end of "local file header" segment
// no "file data"
segment for path
// "data descriptor"
segment (optional but necessary if archive is not served as file)
$fr
.= pack("V",$crc);
//crc32
$fr
.= pack("V",$c_len);
//compressed filesize
$fr
.= pack("V",$unc_len);
//uncompressed filesize
// add this entry to array
$this
-> datasec[]
= $fr;
$new_offset
= strlen(implode("",
$this->datasec));
//
ext. file attributes mirrors MS-DOS directory attr byte, detailed
// at http://support.microsoft.com/support/kb/articles/Q125/0/19.asp
// now add to central record
$cdrec
= "\x50\x4b\x01\x02";
$cdrec
.="\x00\x00"; //
version made by
$cdrec
.="\x0a\x00"; //
version needed to extract
$cdrec
.="\x00\x00"; //
gen purpose bit flag
$cdrec
.="\x00\x00"; //
compression method
$cdrec
.="\x00\x00\x00\x00";
// last mod time & date
$cdrec
.= pack("V",0);
// crc32
$cdrec
.= pack("V",0);
//compressed filesize
$cdrec
.= pack("V",0);
//uncompressed filesize
$cdrec
.= pack("v",
strlen($name)
); //length of filename
$cdrec
.= pack("v",
0 ); //extra
field length
$cdrec
.= pack("v",
0 ); //file
comment length
$cdrec
.= pack("v",
0 ); //disk
number start
$cdrec
.= pack("v",
0 ); //internal
file attributes
$ext
= "\x00\x00\x10\x00";
$ext
= "\xff\xff\xff\xff";
$cdrec
.= pack("V",
16 ); //external
file attributes - 'directory' bit set
$cdrec
.= pack("V",
$this -> old_offset
); //relative offset
of local header
$this
-> old_offset =
$new_offset;
$cdrec
.= $name;
//
optional extra field, file comment goes here
// save to array
$this
-> ctrl_dir[]
= $cdrec;
}
function add_file($data,
$name)
// adds "file" to
archive
// $data - file contents
// $name - name of file in archive. Add path if your
want
{
$name
= str_replace("\\",
"/", $name);
//$name
= str_replace("\\",
"\\\\", $name);
$fr
= "\x50\x4b\x03\x04";
$fr
.= "\x14\x00"; //
ver needed to extract
$fr
.= "\x00\x00"; //
gen purpose bit flag
$fr
.= "\x08\x00"; //
compression method
$fr
.= "\x00\x00\x00\x00";
// last mod time and date
$unc_len
= strlen($data);
$crc
= crc32($data);
$zdata
= gzcompress($data);
$zdata
= substr(
substr($zdata,
0, strlen($zdata)
- 4), 2);
// fix crc bug
$c_len
= strlen($zdata);
$fr
.= pack("V",$crc);
// crc32
$fr
.= pack("V",$c_len);
//compressed filesize
$fr
.= pack("V",$unc_len);
//uncompressed filesize
$fr
.= pack("v",
strlen($name)
); //length of filename
$fr
.= pack("v",
0 ); //extra
field length
$fr
.= $name;
//
end of "local file header" segment
// "file data" segment
$fr
.= $zdata;
//
"data descriptor" segment (optional but necessary if archive is not
served as file)
$fr
.= pack("V",$crc);
//crc32
$fr
.= pack("V",$c_len);
//compressed filesize
$fr
.= pack("V",$unc_len);
//uncompressed filesize
// add this entry to array
$this
-> datasec[]
= $fr;
$new_offset
= strlen(implode("",
$this->datasec));
//
now add to central directory record
$cdrec
= "\x50\x4b\x01\x02";
$cdrec
.="\x00\x00"; //
version made by
$cdrec
.="\x14\x00"; //
version needed to extract
$cdrec
.="\x00\x00"; //
gen purpose bit flag
$cdrec
.="\x08\x00"; //
compression method
$cdrec
.="\x00\x00\x00\x00";
// last mod time & date
$cdrec
.= pack("V",$crc);
// crc32
$cdrec
.= pack("V",$c_len);
//compressed filesize
$cdrec
.= pack("V",$unc_len);
//uncompressed filesize
$cdrec
.= pack("v",
strlen($name)
); //length of filename
$cdrec
.= pack("v",
0 ); //extra
field length
$cdrec
.= pack("v",
0 ); //file
comment length
$cdrec
.= pack("v",
0 ); //disk
number start
$cdrec
.= pack("v",
0 ); //internal
file attributes
$cdrec
.= pack("V",
32 ); //external
file attributes - 'archive' bit set
$cdrec
.= pack("V",
$this -> old_offset
); //relative offset
of local header
// &n;
// bsp; echo "old offset is
".$this->old_offset.", new offset is $new_offset<br>";
$this
-> old_offset =
$new_offset;
$cdrec
.= $name;
//
optional extra field, file comment goes here
// save to central directory
$this
-> ctrl_dir[]
= $cdrec;
}
function file()
{ // dump out file
$data
= implode("",
$this -> datasec);
$ctrldir
= implode("",
$this -> ctrl_dir);
return
$data.
$ctrldir.
$this
-> eof_ctrl_dir.
pack("v",
sizeof($this
-> ctrl_dir)). //
total # of entries "on this disk"
pack("v",
sizeof($this
-> ctrl_dir)). //
total # of entries overall
pack("V",
strlen($ctrldir)). //
size of central dir
pack("V",
strlen($data)). //
offset to start of central dir
"\x00\x00"; //
.zip file comment length
}
}
?>
Example Usage of the
Class
<?php
$zipfile = new zipfile();
// add the subdirectory ... important!
$zipfile -> add_dir("dir/");
// add the binary data stored in the string 'filedata'
$filedata = "(read
your file into $filedata)";
$zipfile -> add_file($filedata,
"dir/file.txt");
// the next three lines force an immediate
download of the zip file:
header("Content-type:
application/octet-stream");
header("Content-disposition:
attachment; filename=test.zip");
echo $zipfile -> file();
// OR instead of doing that, you can write out
the file to the loca disk like this:
$filename = "output.zip";
$fd = fopen
($filename,
"wb");
$out = fwrite
($fd,
$zipfile -> file());
fclose ($fd);
// then offer it to the user to download:
<a href="output.zip">Click
here to download the new zip
file.</a>
?>
| |
Other 6 submission(s) by this author
|
|
|
Report Bad Submission |
|
|
Your Vote! |
See Voting Log |
|
Other User Comments |
4/5/2003 11:00:23 PM: wow thats great! works really good
|
4/5/2003 11:09:32 PM:c0ldfyr3 Neat stuff, thanks.
|
4/6/2003 10:44:47 PM:Tristan Wells Too bad it isnt your code. THis was
ripped from codewalkers.com
|
4/8/2003 4:55:58 AM:Danio Denerio How would you add two files into the
zip file?
|
4/8/2003 4:38:45 PM:Tristan Wells for help, go to codewalkers.com click
php code then file manip, youll find
this very code and info on it there :)
|
4/8/2003 8:38:30 PM:Christian Mallette I found the article on Zend.com,
however I never said I made it myself
so why are people saying I "ripped" the
code. I'm just sharing it with PSC
users.
Quote From Code
Description:
"In this article, which I
found on Zend.com, you'll be able to.
The original version can be found here:
http://www.zend.com/zend/spotlight/creat
ing-zip-files2.php"
|
4/9/2003 9:34:12 PM:Tristan Wells 2) You MAY NOT redistribute this
article (for example to a web site)
without written permission from the
original author. Failure to do so is a
violation of copyright laws. does the
article author even know?
|
4/14/2003 7:06:04 PM:Eric Malamisura Tristan you are incorrect. Copyright
laws only pertain to copying someone
else's work and claiming it as your
own. Everything on the internet is
public source and is qualified for
distribution unless explicitly said not
so on the authors site!
|
4/19/2003 7:47:46 PM:diabloice You lot are a bunch of stuck of XXXXXX
take it if you like it leave it if you
don't no need to therise it and correct
every frigning error.
|
4/25/2003 3:50:55 PM: Tristan grow up... He was sharing with
people that might not visit that site.
|
4/29/2003 1:34:44 AM:rocky03 True!!!
What is the harm in sharing
new stuffs? C'mon have a BIGGER
heart...
Thanks to Christian Mallette
|
5/5/2003 6:50:53 PM: I've ran across this code over at
codewalkers awhile aback. It has been
a great benefit to me, but I wanted
more, so I wrote 2 more classes simular
to this one but instead of zipping, one
that allows you to Tar the file, and
the other allows you to tar.gz the
files, and both work wonderfully.
Hopefully I will have the time to post
them here eventually.
|
5/5/2003 10:38:31 PM:Christian Mallette sounds cool
|
6/17/2003 3:15:08 PM: Can someone please post or email me
working sample code that can zip a
directory which contains files and
other directories. Can you just
specify a dir to zip, or do you have to
recursively go through and add every
file?
|
6/17/2003 3:46:41 PM: I get a "not a valid zip - doesn't
contain ending signature"
??
|
8/13/2003 6:12:24 AM: It works fine.. but just if the
filesize is less than 1700 kb
Is there
someone has gotten the same bug?
|
8/22/2003 4:03:22 PM: i can get this code to work fine!
except my txt files i zip, dont have
return chars or line breaks in them.
they have been replaced by black
squares. this happen to anyone ?
|
8/22/2003 8:49:40 PM:Christian Mallette You see black squares because the files
are saved as BINARY. Try opening the
txt files with WordPad, the black
squares will be replaced with line
breaks.
|
8/25/2003 2:27:36 PM: seems when i open the text or html
files in wordPad i get white squares
with black outline and no linebreaks at
all. does anyone know way to replace
these squares with line breaks before
it zips ?
|
9/15/2003 2:50:53 PM: Does somebody has a nice code for
*extracting* a zip file on the server?
I'm looking for a good one and can't
find. I'd thank for every tip. Write me
to yfurman@yahoo.com.
|
9/29/2003 3:09:32 AM: i dont understand this line
:
$filedata = "(read your file into
$filedata)";
what must i write here
?
does ne1 have a full example ?
|
9/29/2003 4:32:15 PM:Christian Mallette // add the binary data stored in the
string 'filedata'
$filedata = "(read
your file into $filedata)";
$zipfile
-> add_file($filedata, "dir/file.txt");
In that example the content of
$filedata would be what the user would
get when he extracts file.txt.
You
just open up the file you want to add
inside the zip file.
|
10/7/2003 7:29:10 AM: Fentastic piece of code - is there a
uuencode class written to the same high
standard?
Makes perfect winzip
fiiles - you'd never know the
difference!
renows@aol.com
|
10/13/2003 3:44:19 AM: I get this fatal error: Call to
undefined function: gzcompress()
|
10/13/2003 3:45:07 AM: What else do I need to do to get this
working?
Fatal error: Call to
undefined function: gzcompress()
|
10/13/2003 4:36:03 PM:Christian Mallette your missing the zlib compression
module.
|
10/30/2003 10:06:21 PM:psyrod you see the squares instead of line
breaks, simply because unix uses the LF
character as a line break, windows uses
CRLF.
|
11/20/2003 12:36:24 AM: I'm unable to open the output.zip file
in windows, which was created in linux
environment. The error I'm getting is
|
12/19/2003 5:44:55 AM: This is really a very nice tool. Thanx
a lot. For users facing the
|
|
Add Your Feedback! |
Note:Not only will your feedback be posted, but an email will be sent to the code's author in your name.
NOTICE: The author of this article has been kind enough to share it with you. If you have a criticism, please state it politely or it will be deleted.
For feedback not related to this particular article, please click here. |
|