Phpzip file decompression class code
Last Update:2018-04-05
Source: Internet
Author: User
Decompress the zip file using php.
The code is as follows:
Class zip
{
Var $ datasec, $ ctrl_dir = array ();
Var $ eof_ctrl_dir = "\ x50 \ x4b \ x05 \ x06 \ x00 \ x00 \ x00 \ x00 ";
Var $ old_offset = 0; var $ dirs = Array (".");
Function get_List ($ zip_name)
{
$ Zip = @ fopen ($ zip_name, 'RB ');
If (! $ Zip) return (0 );
$ Centd = $ this-> ReadCentralDir ($ zip, $ zip_name );
@ Rewind ($ zip );
@ Fseek ($ zip, $ centd ['offset']);
For ($ I = 0; $ I <$ centd ['entries']; $ I ++)
{
$ Header = $ this-> ReadCentralFileHeaders ($ zip );
$ Header ['index'] = $ I; $ info ['filename'] = $ header ['filename'];
$ Info ['stored _ filename'] = $ header ['stored _ filename'];
$ Info ['size'] = $ header ['size']; $ info ['compressed _ size'] = $ header ['compressed _ size'];
$ Info ['crc '] = strtoupper (dechex ($ header ['crc']);
$ Info ['mtime'] = $ header ['mtime']; $ info ['comment'] = $ header ['comment'];
$ Info ['Folder'] = ($ header ['external '] = 0x41FF0010 | $ header ['external'] = 16 )? 1:0;
$ Info ['index'] = $ header ['index']; $ info ['status'] = $ header ['status'];
$ Ret [] = $ info; unset ($ header );
}
Return $ ret;
}
Function Add ($ files, $ compact)
{
If (! Is_array ($ files [0]) $ files = Array ($ files );
For ($ I = 0; $ files [$ I]; $ I ++ ){
$ Fn = $ files [$ I];
If (! In_Array (dirname ($ fn [0]), $ this-> dirs ))
$ This-> add_Dir (dirname ($ fn [0]);
If (basename ($ fn [0])
$ Ret [basename ($ fn [0])] = $ this-> add_File ($ fn [1], $ fn [0], $ compact );
}
Return $ ret;
}
Function get_file ()
{
$ Data = implode ('', $ this-> datasec );
$ Ctrldir = implode ('', $ this-> ctrl_dir );
Return $ data. $ ctrldir. $ this-> eof_ctrl_dir.
Pack ('v', sizeof ($ this-> ctrl_dir). pack ('v', sizeof ($ this-> ctrl_dir )).
Pack ('v', strlen ($ ctrldir). pack ('v', strlen ($ data). "\ x00 \ x00 ";
}
Function add_dir ($ name)
{
$ Name = str_replace ("\", "/", $ name );
$ Fr = "\ x50 \ x4b \ x03 \ x04 \ x0a \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 ";
$ Fr. = pack ("V", 0 ). pack ("V", 0 ). pack ("V", 0 ). pack ("v", strlen ($ name ));
$ Fr. = pack ("v", 0 ). $ name. pack ("V", 0 ). pack ("V", 0 ). pack ("V", 0 );
$ This-> datasec [] = $ fr;
$ New_offset = strlen (implode ("", $ this-> datasec ));
$ Cdrec = "\ x50 \ x4b \ x01 \ x02 \ x00 \ x00 \ x0a \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 ";
$ Cdrec. = pack ("V", 0 ). pack ("V", 0 ). pack ("V", 0 ). pack ("v", strlen ($ name ));
$ Cdrec. = pack ("v", 0). pack ("v", 0). pack ("v", 0). pack ("v", 0 );
$ Ext = "\ xff ";
$ Cdrec. = pack ("V", 16). pack ("V", $ this-> old_offset). $ name;
$ This-> ctrl_dir [] = $ cdrec;
$ This-> old_offset = $ new_offset;
$ This-> dirs [] = $ name;
}
Function add_File ($ data, $ name, $ compact = 1)
{
$ Name = str_replace ('\', '/', $ name );
$ Dtime = dechex ($ this-> DosTime ());
$ Hexdtime = '\ X'. $ dtime [6]. $ dtime [7].' \ X'. $ dtime [4]. $ dtime [5]
. '\ X'. $ dtime [2]. $ dtime [3].' \ X'. $ dtime [0]. $ dtime [1];
Eval ('$ hexdtime = "'. $ hexdtime .'";');
If ($ compact)
$ Fr = "\ x50 \ x4b \ x03 \ x04 \ x14 \ x00 \ x00 \ x00 \ x08 \ x00". $ hexdtime;
Else $ fr = "\ x50 \ x4b \ x03 \ x04 \ x0a \ x00 \ x00 \ x00 \ x00 \ x00". $ hexdtime;
$ Unc_len = strlen ($ data); $ crc = crc32 ($ data );
If ($ compact ){
$ Zdata = gzcompress ($ data); $ c_len = strlen ($ zdata );
$ Zdata = substr ($ zdata, 0, strlen ($ zdata)-4), 2 );
} Else {
$ Zdata = $ data;
}
$ C_len = strlen ($ zdata );
$ Fr. = pack ('v', $ crc). pack ('v', $ c_len). pack ('v', $ unc_len );
$ Fr. = pack ('v', strlen ($ name). pack ('v', 0). $ name. $ zdata;
$ Fr. = pack ('v', $ crc). pack ('v', $ c_len). pack ('v', $ unc_len );
$ This-> datasec [] = $ fr;
$ New_offset = strlen (implode ('', $ this-> datasec ));
If ($ compact)
$ Cdrec = "\ x50 \ x4b \ x01 \ x02 \ x00 \ x00 \ x14 \ x00 \ x00 \ x00 \ x08 \ x00 ";
Else $ cdrec = "\ x50 \ x4b \ x01 \ x02 \ x14 \ x00 \ x0a \ x00 \ x00 \ x00 \ x00 \ x00 ";
$ Cdrec. = $ hexdtime. pack ('v', $ crc). pack ('v', $ c_len). pack ('v', $ unc_len );
$ Cdrec. = pack ('v', strlen ($ name). pack ('v', 0). pack ('v', 0 );
$ Cdrec. = pack ('v', 0). pack ('v', 0). pack ('v', 32 );
$ Cdrec. = pack ('v', $ this-> old_offset );
$ This-> old_offset = $ new_offset;
$ Cdrec. = $ name;
$ This-> ctrl_dir [] = $ cdrec;
Return true;
}
Function DosTime (){
$ Timearray = getdate ();
If ($ timearray ['Year'] <1980 ){
$ Timearray ['Year'] = 1980; $ timearray ['mon'] = 1;
$ Timearray ['mday'] = 1; $ timearray ['hours'] = 0;
$ Timearray ['minutes '] = 0; $ timearray ['seconds'] = 0;
}
Return ($ timearray ['Year']-1980) <25) | ($ timearray ['mon'] <21) | ($ timearray ['mday'] <16) | ($ timearray ['hours'] <11) |
($ Timearray ['minutes '] <5) | ($ timearray ['seconds']> 1 );
}
Function Extract ($ zn, $ to, $ index = Array (-1 ))
{
$ OK = 0; $ zip = @ fopen ($ zn, 'RB ');
If (! $ Zip) return (-1 );
$ Cdir = $ this-> ReadCentralDir ($ zip, $ zn );
$ Pos_entry = $ cdir ['offset'];
If (! Is_array ($ index) {$ index = array ($ index );}
For ($ I = 0; $ index [$ I]; $ I ++ ){
If (intval ($ index [$ I])! = $ Index [$ I] | $ index [$ I]> $ cdir ['entries'])
Return (-1 );
}
For ($ I = 0; $ I <$ cdir ['entries']; $ I ++)
{
@ Fseek ($ zip, $ pos_entry );
$ Header = $ this-> ReadCentralFileHeaders ($ zip );
$ Header ['index'] = $ I; $ pos_entry = ftell ($ zip );
@ Rewind ($ zip); fseek ($ zip, $ header ['offset']);
If (in_array ("-1", $ index) | in_array ($ I, $ index ))
$ Stat [$ header ['filename'] = $ this-> ExtractFile ($ header, $ to, $ zip );
}
Fclose ($ zip );
Return $ stat;
}
Function ReadFileHeader ($ zip)
{
$ Binary_data = fread ($ zip, 30 );
$ Data = unpack ('vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len ', $ binary_data );
$ Header ['filename'] = fread ($ zip, $ data ['filename _ Len']);
If ($ data ['extra _ Len']! = 0 ){
$ Header ['Extra '] = fread ($ zip, $ data ['extra _ Len']);
} Else {$ header ['Extra '] = '';}
$ Header ['compression'] = $ data ['compression']; $ header ['size'] = $ data ['size'];
$ Header ['compressed _ size'] = $ data ['compressed _ size'];
$ Header ['crc '] = $ data ['crc']; $ header ['flag'] = $ data ['flag'];
$ Header ['mdate'] = $ data ['mdate']; $ header ['mtime'] = $ data ['mtime'];
If ($ header ['mdate'] & $ header ['mtime']) {
$ Hour = ($ header ['mtime'] & 0xF800)> 11; $ minute = ($ header ['mtime'] & 0x07E0)> 5;
$ Seconde = ($ header ['mtime'] & 0x001F) * 2; $ year = ($ header ['mdate'] & 0xFE00)> 9) + 1980;
$ Month = ($ header ['mdate'] & 0x01E0)> 5; $ day = $ header ['mdate'] & 0x001F;
$ Header ['mtime'] = mktime ($ hour, $ minute, $ seconde, $ month, $ day, $ year );
} Else {$ header ['mtime'] = time ();}
$ Header ['stored _ filename'] = $ header ['filename'];
$ Header ['status'] = "OK ";
Return $ header;
}
Function ReadCentralFileHeaders ($ zip ){
$ Binary_data = fread ($ zip, 46 );
$ Header = unpack ('vchkid/vid/vversion/kernel/vflag/vcompression/vmtime/vmdate/Vcrc/kernel/Vsize/kernel/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/ voffset ', $ binary_data );
If ($ header ['filename _ Len']! = 0)
$ Header ['filename'] = fread ($ zip, $ header ['filename _ Len']);
Else $ header ['filename'] = '';
If ($ header ['extra _ Len']! = 0)
$ Header ['Extra '] = fread ($ zip, $ header ['extra _ Len']);
Else $ header ['Extra '] = '';
If ($ header ['Comment _ Len']! = 0)
$ Header ['comment'] = fread ($ zip, $ header ['Comment _ Len']);
Else $ header ['comment'] = '';
If ($ header ['mdate'] & $ header ['mtime'])
{
$ Hour = ($ header ['mtime'] & 0xF800)> 11;
$ Minute = ($ header ['mtime'] & 0x07E0)> 5;
$ Seconde = ($ header ['mtime'] & 0x001F) * 2;
$ Year = ($ header ['mdate'] & 0xFE00)> 9) + 1980;
$ Month = ($ header ['mdate'] & 0x01E0)> 5;
$ Day = $ header ['mdate'] & 0x001F;
$ Header ['mtime'] = mktime ($ hour, $ minute, $ seconde, $ month, $ day, $ year );
} Else {
$ Header ['mtime'] = time ();
}
$ Header ['stored _ filename'] = $ header ['filename'];
$ Header ['status'] = 'OK ';
If (substr ($ header ['filename'],-1) = '/')
$ Header ['external '] = 0x41FF0010;
Return $ header;
}
Function ReadCentralDir ($ zip, $ zip_name)
{
$ Size = filesize ($ zip_name );
If ($ size <277) $ maximum_size = $ size;
Else $ maximum_size = 277;
@ Fseek ($ zip, $ size-$ maximum_size );
$ Pos = ftell ($ zip); $ bytes = 0x00000000;
While ($ pos <$ size)
{
$ Byte = @ fread ($ zip, 1); $ bytes = ($ bytes <8) | Ord ($ byte );
If ($ bytes = 0x504b0506) {$ pos ++; break;} $ pos ++;
}
$ Data = unpack ('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size ',
Fread ($ zip, 18 ));
If ($ data ['Comment _ size']! = 0)
$ Centd ['comment'] = fread ($ zip, $ data ['Comment _ size']);
Else $ centd ['comment'] = ''; $ centd ['entries'] = $ data ['entries'];
$ Centd ['disk _ entries'] = $ data ['disk _ entries'];
$ Centd ['offset'] = $ data ['offset']; $ centd ['disk _ start'] = $ data ['disk _ start'];
$ Centd ['size'] = $ data ['size']; $ centd ['disk'] = $ data ['disk'];
Return $ centd;
}
Function ExtractFile ($ header, $ to, $ zip)
{
$ Header = $ this-> readfileheader ($ zip );
If (substr ($ to,-1 )! = "/") $ To. = "/";
If (! @ Is_dir ($ to) @ mkdir ($ to, 0777 );
$ Pth = explode ("/", dirname ($ header ['filename']);
For ($ I = 0; isset ($ pth [$ I]); $ I ++ ){
If (! $ Pth [$ I]) continue;
If (! Is_dir ($ to. $ pth [$ I]) @ mkdir ($ to. $ pth [$ I], 0777 );
}
If (! ($ Header ['external '] = 0x41FF0010 )&&! ($ Header ['external '] = 16 ))
{
If ($ header ['compression'] = 0)
{
$ Fp = @ fopen ($ to. $ header ['filename'], 'wb ');
If (! $ Fp) return (-1 );
$ Size = $ header ['compressed _ size'];
While ($ size! = 0)
{
$ Read_size = ($ size <2048? $ Size: 2048 );
$ Buffer = fread ($ zip, $ read_size );
$ Binary_data = pack ('A'. $ read_size, $ buffer );
@ Fwrite ($ fp, $ binary_data, $ read_size );
$ Size-= $ read_size;
}
Fclose ($ fp );
Touch ($ to. $ header ['filename'], $ header ['mtime']);
} Else {
$ Fp = @fopen($to.w.header='filename'{.'.gz ', 'wb ');
If (! $ Fp) return (-1 );
$ Binary_data = pack ('va1a1va1a1 ', 0x8b1f, Chr ($ header ['compression']),
Chr (0x00), time (), Chr (0x00), Chr (3 ));
Fwrite ($ fp, $ binary_data, 10 );
$ Size = $ header ['compressed _ size'];
While ($ size! = 0)
{
$ Read_size = ($ size <1024? $ Size: 1024 );
$ Buffer = fread ($ zip, $ read_size );
$ Binary_data = pack ('A'. $ read_size, $ buffer );
@ Fwrite ($ fp, $ binary_data, $ read_size );
$ Size-= $ read_size;
}
$ Binary_data = pack ('vv ', $ header ['crc'], $ header ['size']);
Fwrite ($ fp, $ binary_data, 8); fclose ($ fp );
$ Gzp = @gzopen({to.w.header='filename'{.'.gz ', 'RB') or die ("Cette archive est compress compression ");
If (! $ Gzp) return (-2 );
$ Fp = @ fopen ($ to. $ header ['filename'], 'wb ');
If (! $ Fp) return (-1 );
$ Size = $ header ['size'];
While ($ size! = 0)
{
$ Read_size = ($ size <2048? $ Size: 2048 );
$ Buffer = gzread ($ gzp, $ read_size );
$ Binary_data = pack ('A'. $ read_size, $ buffer );
@ Fwrite ($ fp, $ binary_data, $ read_size );
$ Size-= $ read_size;
}
Fclose ($ fp); gzclose ($ gzp );
Touch ($ to. $ header ['filename'], $ header ['mtime']);
@ Unlink(%to.%header%'filename'%.'.gz ');
}}
Return true;
}
}
/***********************************/
Class zipPeter {
Var $ _ zip_hander = null;
Function _ construct (){
}
Function get_List ($ zip_name ){
$ File_list = array ();
$ This-> _ zip_hander = zip_open ($ zip_name );
If ($ this-> _ zip_hander ){
While ($ zip_entry = zip_read ($ this-> _ zip_hander )){
$ File_list [] = array ('filename' => zip_entry_name ($ zip_entry ),
'Size' => zip_entry_filesize ($ zip_entry ),
'Compressed _ size' => zip_entry_compressedsize ($ zip_entry)
);
}
Zip_close ($ this-> _ zip_hander );
}
Return $ file_list;
}
Function Extract ($ zip_name, $ folder_name ){
$ This-> _ zip_hander = zip_open ($ zip_name );
If (! $ This-> checkDirAndMk ($ folder_name )){
Return false;
}
If (substr ($ folder_name,-1 )! = "/"){
$ Folder_name. = "/";
}
If ($ this-> _ zip_hander ){
While ($ zip_entry = zip_read ($ this-> _ zip_hander )){
$ File_info = array ('filename' => zip_entry_name ($ zip_entry ),
'Size' => zip_entry_filesize ($ zip_entry ),
'Compressed _ size' => zip_entry_compressedsize ($ zip_entry)
);
$ New_file_name = $ folder_name. $ file_info ['filename'];
$ Buf = "";
If (zip_entry_open ($ this-> _ zip_hander, $ zip_entry, "r ")){
$ Buf = zip_entry_read ($ zip_entry, zip_entry_filesize ($ zip_entry ));
Zip_entry_close ($ zip_entry );
}
If ($ fp = fopen ($ new_file_name, "w ")){
Fwrite ($ fp, $ buf );
Fclose ($ fp );
}
}
Zip_close ($ this-> _ zip_hander );
Return true;
}
Else {
Return false;
}
}
/**
* Check whether the directory exists. if not, check whether the directory is created.
*
* @ Param string $ complete actual path of dirname
* @ Param bool $ mk whether to create a database if it does not exist
* @ Param int $ mode: create permission
* @ Return whether bool is successfully created
*/
Function checkDirAndMk ($ dirname, $ mk = false, $ mode = 0777 ){
If (is_dir ($ dirname) = true ){
Return true;
}
Else {
If ($ mk = false ){
Return false;
}
Else {
$ Dirpath_a = explode ('/', $ dirname );
For ($ I = 0; $ I If ($ dirpath_a [$ I] = ""){
Continue;
}
If ($ path = "" | is_dir ($ path )){
If ($ path = ""){
If (substr (PHP_ OS, 0, 3) = "WIN "){
$ Path = $ dirpath_a [$ I];
}
Else {
$ Path. = "/". $ dirpath_a [$ I];
}
}
Else {
$ Path. = "/". $ dirpath_a [$ I];
}
If (is_dir ($ path )){
Continue;
}
Else {
@ Mkdir ($ path, $ mode );
}
}
Else {
Return false;
}
}
Return true;
}
}
}
}
$ Z = new Zip;
$ Lst = $ z-> get_list('test2.zip ');
Foreach ($ lst as $ val ){
Print_r ($ val). "\ n ";
}
$ Zip_obj = new zipPeter ();
// $ Zip_obj-> Extract ()
$ Z-> Extract('test2.zip ', "f:/wytddd",-1 );
/***/
Require_once ("zip. lib. php ");
Set_time_limit (100 );
// File path to be decompressed
$ Arch = $ _ GET ["arch"];
If (! $ Arch |! File_exists ($ arch ))
$ Z = new Zip;
$ L = $ z-> get_list ($ arch); // get the file list
$ Z-> Extract ($ arch, "jieya",-1 );
}