php coders

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Dugan
    Confirmed User
    • Nov 2003
    • 856

    #1

    php coders

    Does anyone know if theres a simple way to zip up a directory....theres all kinds of unzip functions, and i've been looking at the zlibs for gzipping, but i can't seem to find one that actually zips up a directory rather than one file....
  • Napolean
    Misanthropic Egalitarian
    • Nov 2002
    • 4330

    #2
    havent tested this out yet.. but worth a shot??
    ---
    <?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, [email protected], 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.../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>

    ?>
    HAH! FOUND IT FRIS

    Comment

    • AvanteGuard
      Confirmed User
      • Jan 2004
      • 451

      #3
      PHP Code:
      Zip a directory structure on the fly and deliver it via http using PHP
      For offline-browsing, it is often convinient to download a whole directory structure and read it offline. That is especially true for photos hahahahahaed in html. 
      Instead of offering a zipped archive, which needs maintanance whenever something changes, it is possible to do a bit of php and just zip the stuff on the fly when it is acutually requested. 
      
      The introduced bit of php must have the same name as the directory structure (plus .php as extension) to zip and must reside in the same directory (as the source directory). 
      
      That's all! 
      
      For the zip, just link to the php and the visitor gets prompted where to store the stuff. Try it here (link to ../ontheflyzip.php). 
      
      This is the .php: 
      
      <?PHP
      
      // this script zips up a directory (on the fly) and delivers it
      // C.Kaiser 2002
      // No Copyright, free to use.
      
        // get the filename of this php file without extension.
        // that is also the directory to zip and the name of the
        // zip file to deliver
        $filename_no_ext=str_replace(".php","",basename($SCRIPT_NAME));
      
        // we deliver a zip file
        header("Content-Type: archive/zip");
      
        // filename for the browser to save the zip file
        header("Content-Disposition: attachment; filename=$filename_no_ext".".zip");
      
        // get a tmp name for the .zip
        $tmp_zip = tempnam ("tmp", "tempname") . ".zip";
      
        // zip the stuff (dir and all in there) into the tmp_zip file
        `zip -r $tmp_zip $filename_no_ext`;
       
        // calc the length of the zip. it is needed for the progress bar of the browser
        $filesize = filesize($tmp_zip);
        header("Content-Length: $filesize");
      
        // deliver the zip file
        $fp = fopen("$tmp_zip","r");
        echo fpassthru($fp);
      
        // clean up the tmp zip file
        `rm $tmp_zip `;
      ?>
      The .php file must not have any characters (including blanks or blank lines) prior the "<?PHP.." cause otherwise a default http header is created rather than the one constructed within the php. 
      If your directory to zip is named dir, the php must be named dir.php.
      Looking for Fast Professional Programming? http://www.imadigan.com
      ICQ: 314-942-262 | MSN/Email: [email protected]

      Comment

      • Dugan
        Confirmed User
        • Nov 2003
        • 856

        #4
        thanks guys, i'll try those out and let you know what i come up with...

        Comment

        • Lane
          Will code for food...
          • Apr 2001
          • 8496

          #5
          u can simply use gzip, just like from the command line..
          system() function will let you execute any shell command from your script

          Comment

          • vending_machine
            Confirmed User
            • Jun 2002
            • 1070

            #6
            Originally posted by TheNewKid
            Does anyone know if theres a simple way to zip up a directory....theres all kinds of unzip functions, and i've been looking at the zlibs for gzipping, but i can't seem to find one that actually zips up a directory rather than one file....
            The comment section in the manual has plenty of suggestions
            http://us2.php.net/manual/en/ref.zip.php

            Comment

            • Dugan
              Confirmed User
              • Nov 2003
              • 856

              #7
              Originally posted by Lane
              u can simply use gzip, just like from the command line..
              system() function will let you execute any shell command from your script
              yeah, you know what, that'd probably be the simplest way to do it.....i was gonna try and make it more versatile, like able to use in windows and shit....but who cares. i think i'll go with that.

              Comment

              • Dugan
                Confirmed User
                • Nov 2003
                • 856

                #8
                Originally posted by Napolean
                havent tested this out yet.. but worth a shot??
                ---
                <?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, [email protected], 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.../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>

                ?>
                This one worked kick ass in case anyones wondering

                Comment

                • Ash@phpFX
                  Confirmed User
                  • Nov 2003
                  • 4292

                  #9
                  ill have to bookmark this one

                  Comment

                  Working...