Zip Klasse
Klasse mit der sich zip-files erstellen lassen
|
Script: |
<?php
class ZipBuilder {
var $datasec = array(); // array to store compressed data
var $ctrl_dir = array(); // central directory
var $eof_ctrl_dir = "x50x4bx05x06x00x00x00x00"; //end of Central directory record
var $old_offset = 0;
function ZipBuilder()
{
}
function getDosDatetime($date = 0)
{
if (!$date)
$date = date("Y-m-d H:i:s", time());
$regexp = "([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})";
$date = ereg_replace($regexp, "\1-\2-\3-\4-\5-\6", $date);
$date_array = split("-", $date);
$date_array[0] = $date_array[0]-1980;
$date_day = $date_array[2];
$date_month = $date_array[1];
$date_year = $date_array[0];
$date_hour = $date_array[3];
$date_minute = $date_array[4];
$date_second = $date_array[5];
$my_time = $date_hour;
$my_time = ($my_time << 6) + $date_minute;
$my_time = ($my_time << 5) + number_format($date_second / 2, 0);
$time_right = $my_time >> 8;
$time_left = $my_time - ($time_right << 8);
$my_date = $date_year;
$my_date = ($my_date << 4) + $date_month;
$my_date = ($my_date << 5) + $date_day;
$date_right = $my_date >> 8;
$date_left = $my_date - ($date_right << 8);
$time_left = sprintf("%02x", $time_left);
$time_right = sprintf("%02x", $time_right);
$date_left = sprintf("%02x", $date_left);
$date_right = sprintf("%02x", $date_right);
return pack("H*H*H*H*", $time_left, $time_right, $date_left, $date_right);
}
function add_path($name, $date = 0)
// 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 = "x50x4bx03x04";
$fr .= "x0ax00"; // ver needed to extract
$fr .= "x00x00"; // gen purpose bit flag
$fr .= function_exists('gzcompress')?"x08x00":"x00x00"; // compression method
$fr .= "x00x00x00x00"; // 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;
$fr .= pack("V", 0); //crc32
$fr .= pack("V", 0); //compressed filesize
$fr .= pack("V", 0); //uncompressed filesize
$this -> datasec[] = $fr;
$new_offset = strlen(implode("", $this->datasec));
$cdrec = "x50x4bx01x02";
$cdrec .= "x00x00"; // version made by
$cdrec .= "x0ax00"; // version needed to extract
$cdrec .= "x00x00"; // gen purpose bit flag
$cdrec .= function_exists('gzcompress')?"x08x00":"x00x00"; // compression method
$cdrec .= $this->getDosDatetime($date); // 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 = "x00x00x10x00";
$ext = "xffxffxffxff";
$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;
$this -> ctrl_dir[] = $cdrec;
}
function add_file($file)
{
// $filedata='';
$fd = fopen ($file, "rb");
$filedata = fread($fd, filesize($file));
$this->add_data($filedata, $file);
}
function add_data($data, $name, $date = 0)
// 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 = "x50x4bx03x04";
$fr .= "x14x00"; // ver needed to extract
$fr .= "x00x00"; // gen purpose bit flag
$fr .= function_exists('gzcompress')?"x08x00":"x00x00"; // compression method
$fr .= "x00x00x00x00"; // last mod time and date
$unc_len = strlen($data);
$crc = crc32($data);
if (function_exists('gzcompress')) {
$zdata = gzcompress($data);
$zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
} else {
$zdata = $data;
}
$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 = "x50x4bx01x02";
$cdrec .= "x00x00"; // version made by
$cdrec .= "x14x00"; // version needed to extract
$cdrec .= "x00x00"; // gen purpose bit flag
$cdrec .= "x08x00"; // compression method
$cdrec .= $this->getDosDatetime($date);
// $cdrec .="x00x00x00x00"; // 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
"x00x00"; // .zip file comment length
}
function download($zip_name)
{
header("Content-type: application/octet-stream");
header("Content-disposition: attachment; filename=" . $zip_name . ".zip");
echo $this -> file();
}
function save($name)
{
$fd = fopen ($name, "wb");
$out = fwrite ($fd, $this-> file());
fclose ($fd);
}
// for unpack !!! => dosn't work with gzuncompress because CRC Fix !!!
/**
* from end to start of file !
* 16 Bit - zip file comment length
* 32 Bit - offset to start of central dir
* 32 Bit - size of central dir
* 16 Bit - total entries over all
* 16 Bit - total entries this disk
* eof central dir : "x50x4bx05x06x00x00x00x00"
* central dir
* data
*/
}
?>
|
|