The following zip creation class by Eric Mueller works well:

<?php 

/* 

Zip file creation class 
makes zip files... 

use the functions add_dir() and add_file() to build the zip file; 
see example code below 


by Eric Mueller, [EMAIL PROTECTED], http://www.themepark.com 

BASED ON "zip file creation class" 
FOUND AT http://www.zend.com/codex.php?id=470&single=1 
BY denis125 ([EMAIL PROTECTED]) 

*/ 

// 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 
//        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  
<?php  
$zipfile = new zipfile();  

$zipfile -> add_dir("dir/"); 

$filedata = "read your file into filedata";  
$zipfile -> add_file($filedata, "dir/file.txt");  

header("Content-type: application/octet-stream");  
header("Content-disposition: attachment; filename=test.zip");  
echo $zipfile -> file();  

// note that instead of doing header/echo, you could use fopen/fwrite/fclose
to write the .zip file to disk... 

?> 

-----Original Message-----
From: Rahul [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, August 13, 2002 2:41 PM
To: [EMAIL PROTECTED]
Subject: [PHP] Creating a zip file using php


Hi

I want to create a zip file using php. Can this be done?

If anybody has a code snippet, for this, or any guidelines, please send it
to me.

Rahul




-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to