真正的ZIP文件操作类(php)
真正的ZIP文件操作类(php)
发布时间:2016-12-29 来源:查字典编辑
摘要:

<?

/********************

作者未知

整理:Longbill(www.longbill.cn;longbill.cn@gmail.com)

*********************/

classzip

{

var$datasec,$ctrl_dir=array();

var$eof_ctrl_dir="x50x4bx05x06x00x00x00x00";

var$old_offset=0;var$dirs=Array(".");

functionget_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;

}

functionAdd($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;

}

functionget_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))."x00x00";

}

functionadd_dir($name)

{

$name=str_replace("","/",$name);

$fr="x50x4bx03x04x0ax00x00x00x00x00x00x00x00x00";

$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="x50x4bx01x02x00x00x0ax00x00x00x00x00x00x00x00x00";

$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="xffxffxffxff";

$cdrec.=pack("V",16).pack("V",$this->old_offset).$name;

$this->ctrl_dir[]=$cdrec;

$this->old_offset=$new_offset;

$this->dirs[]=$name;

}

functionadd_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="x50x4bx03x04x14x00x00x00x08x00".$hexdtime;

else$fr="x50x4bx03x04x0ax00x00x00x00x00".$hexdtime;

$unc_len=strlen($data);$crc=crc32($data);

if($compact){

$zdata=gzcompress($data);$c_len=strlen($zdata);

$zdata=substr(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="x50x4bx01x02x00x00x14x00x00x00x08x00";

else$cdrec="x50x4bx01x02x14x00x0ax00x00x00x00x00";

$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;

returntrue;

}

functionDosTime(){

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

}

functionExtract($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;

}

functionReadFileHeader($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;

}

functionReadCentralFileHeaders($zip){

$binary_data=fread($zip,46);

$header=unpack('vchkid/vid/vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/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;

}

functionReadCentralDir($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;

}

functionExtractFile($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;$pthss.=$pth[$i]."/";

if(!is_dir($to.$pthss))@mkdir($to.$pthss,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.$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.$header['filename'].'.gz','rb')ordie("Cettearchiveestcompress");

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

}}

returntrue;

}

}

?>

打包文件下载

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新php教程学习
热门php教程学习
编程开发子分类