Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

php zip a directory plus zip a text file on the fly!

Posted on 2004-11-03
2
Medium Priority
?
496 Views
Last Modified: 2012-05-05
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("hidden/filestobeziped");


//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);

      }

}

/////////////////////////Orginal////////////////////////////
//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-disposition: attachment; filename=phprocketbanner.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>

*/


======================================================================

Here is the error I am getting...

Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html/members/access/product1/download.php on line 119

Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html/members/access/product1/download.php on line 119

Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html/members/access/product1/download.php on line 119

Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html/members/access/product1/download.php on line 119

Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html/members/access/product1/download.php on line 119

Warning: crc32() expects parameter 1 to be string, resource given in /home/phprock1/public_html/members/access/product1/download.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.
0
Comment
Question by:daveaton
2 Comments
 
LVL 48

Accepted Solution

by:
hernst42 earned 2000 total points
ID: 12490747
This code is giving you that error:

    if (stristr($proccessed, ".")) {
          $fd = fopen ($proccessed, "r");
          //Add a File in the zip
          $zipfile -> add_file($fd, $proccessed);
          fclose ($fd);
          }


Try
    if (stristr($proccessed, ".")) {
          $fd = file_get_contents($proccessed);
          //Add a File in the zip
          $zipfile -> add_file($fd, $proccessed);
          }

You can not give the filepointer to the add:file -function you need to give the content of that file to that function
0
 
LVL 2

Author Comment

by:daveaton
ID: 12496144
Well with the modification I do not get the error and when I download the zip all the files are 0KB it downloads the names but, the files do not contain anything... Any more suppestions ?
0

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
There are times when I have encountered the need to decompress a response from a PHP request. This is how it's done, but you must have control of the request and you can set the Accept-Encoding header.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
Suggested Courses

578 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question