daveaton
asked on
php zip a directory plus zip a text file on the fly!
Ok here is what I am tring to do..
I am trying to set a path for php to zip a directory recursively then add a on the fly text file to the zip..
I have found a script that I modified that will do on the fly.. but what I am having trouble with it will not do binary files such
as graphic images now.. it's stuck on text.. also when I use fopen to open a file to read it, it does not like that either now.
the only way it will add files is if I generated them on the fly.. Here is the code below.. I have commented the best I could.
========================== ========== ========== ========== ========== ====
/*
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); ////////////disabled for testing
$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
}
}
/////My Modification to spit out the directory recursively///////////////
////Hopefully directorys are listed first../////////
//list the directory recursively
function make_tree($path){ //where $path is your source dir.
$handle=opendir($path);
while($a=readdir($handle)) {
if(!preg_match('/^\./',$a) ){
$full_path="$path/$a";
$list[]=$full_path;
if(is_dir($full_path)){
$recursive=make_tree($full _path);
for($n=0; $n<count($recursive); $n++){
$list[]=$recursive[$n];
}
}
}
}
closedir($handle);
return $list;
}
$zipfile = new zipfile();
//Start Here where to start adding file from...
///http://www.mysite.com/hidden/banner
$dirfiles=make_tree("hidde n/filestob eziped");
//Loop thru each file or dir name
foreach ($dirfiles as $proccessed) {
//If we find a "." it's a file.
//Other wise it's a directory
if (stristr($proccessed, ".")) {
$fd = fopen ($proccessed, "r");
//Add a File in the zip
$zipfile -> add_file($fd, $proccessed);
fclose ($fd);
}
else {
//Add a Directory name in the zip.. must be done before file is added.
$zipfile -> add_dir($proccessed);
}
}
/////////////////////////O rginal//// ////////// ////////// ////
//I replaced this with the above code
//Add your directory name first very important
$zipfile -> add_dir("yourfilename");
// add the binary data stored in the string 'filedata'
//$filedata = "(read your file into $filedata)";
//$zipfile -> add_file($filedata, "yourfilename/test.txt");
////////////////////////// ////////// ////////// ////////// ////////// /
// the next three lines force an immediate download of the zip file:
header("Content-type: application/octet-stream") ;
header("Content-dispositio n: attachment; filename=phprocketbanner.z ip");
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>
*/
========================== ========== ========== ========== ========== ====
Here is the error I am getting...
Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html /members/a ccess/prod uct1/downl oad.php on line 119
Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html /members/a ccess/prod uct1/downl oad.php on line 119
Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html /members/a ccess/prod uct1/downl oad.php on line 119
Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html /members/a ccess/prod uct1/downl oad.php on line 119
Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html /members/a ccess/prod uct1/downl oad.php on line 119
Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html /members/a ccess/prod uct1/downl oad.php on line 119
I guess the reason why is that crc32 is expecting text or a string.. how can this be done for like graphics, and the .php files are strings arent they ?
Any help would be greatly appreciated.
I am trying to set a path for php to zip a directory recursively then add a on the fly text file to the zip..
I have found a script that I modified that will do on the fly.. but what I am having trouble with it will not do binary files such
as graphic images now.. it's stuck on text.. also when I use fopen to open a file to read it, it does not like that either now.
the only way it will add files is if I generated them on the fly.. Here is the code below.. I have commented the best I could.
==========================
/*
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\
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); ////////////disabled for testing
$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
}
}
/////My Modification to spit out the directory recursively///////////////
////Hopefully directorys are listed first../////////
//list the directory recursively
function make_tree($path){ //where $path is your source dir.
$handle=opendir($path);
while($a=readdir($handle))
if(!preg_match('/^\./',$a)
$full_path="$path/$a";
$list[]=$full_path;
if(is_dir($full_path)){
$recursive=make_tree($full
for($n=0; $n<count($recursive); $n++){
$list[]=$recursive[$n];
}
}
}
}
closedir($handle);
return $list;
}
$zipfile = new zipfile();
//Start Here where to start adding file from...
///http://www.mysite.com/hidden/banner
$dirfiles=make_tree("hidde
//Loop thru each file or dir name
foreach ($dirfiles as $proccessed) {
//If we find a "." it's a file.
//Other wise it's a directory
if (stristr($proccessed, ".")) {
$fd = fopen ($proccessed, "r");
//Add a File in the zip
$zipfile -> add_file($fd, $proccessed);
fclose ($fd);
}
else {
//Add a Directory name in the zip.. must be done before file is added.
$zipfile -> add_dir($proccessed);
}
}
/////////////////////////O
//I replaced this with the above code
//Add your directory name first very important
$zipfile -> add_dir("yourfilename");
// add the binary data stored in the string 'filedata'
//$filedata = "(read your file into $filedata)";
//$zipfile -> add_file($filedata, "yourfilename/test.txt");
//////////////////////////
// the next three lines force an immediate download of the zip file:
header("Content-type: application/octet-stream")
header("Content-dispositio
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>
*/
==========================
Here is the error I am getting...
Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html
Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html
Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html
Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html
Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html
Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html
I guess the reason why is that crc32 is expecting text or a string.. how can this be done for like graphics, and the .php files are strings arent they ?
Any help would be greatly appreciated.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER