PHP解压ZIP的一个类

 

  //以下是类及函数定义

  class Zip //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\xff\xff\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(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/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;

  }

  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;$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') or die("Cette archive est compress閑");

  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;

  }

  } //ZIP压缩类end

时间: 2024-09-17 03:54:01

PHP解压ZIP的一个类的相关文章

php在线解压ZIP文件的方法

这篇文章主要介绍了php在线解压ZIP文件的方法,包含了较为完整的上传与zip解压功能,非常具有实用价值,需要的朋友可以参考下     本文实例讲述了php在线解压ZIP文件的方法.分享给大家供大家参考.具体分析如下: 在PHP的函数库中只找到了个ZLIB的函数还跟压缩有点关系,但是使我失望的是他没能解ZIP的文件,但最后还是让我找到了解决的方法,就是通过PHP的程序执行函数来实现这个功能,因为现在能解ZIP文件的东西实在是太多啦,你要是不信,可以到有下载软件的地方找找看,保准你不会失望的,我的

redhat下安装mysql 5.6.20,解压zip包,查看已经安装过的mysql,卸载rpm安装包,安装mysql服务器端和客户端,修改mysql用户名,登陆mysql,启动关闭mysql

 1 将相关的mysql rpm包上传到redhat上 2  我的电脑是Redhat 6.*版本,所以这里使用上面一个 3  解压zip包 4  安装以下几个rpm MySQL-client-advanced-5.6.20-1.el6.x86_64.rpm MySQL-server-advanced-5.6.20-1.el6.x86_64.rpm 5  查看已经安装过的mysql rpm –aq | grep mysql 结果: mysql-libs-5.1.66-2.el6_3.x86_6

c++-[zlib使用问题]如何解压zip文件!求助各位大神,救急!!!

问题描述 [zlib使用问题]如何解压zip文件!求助各位大神,救急!!! 有个项目,要实现Zip文件的解压和压缩,这几天一直在搞zlib,但是不管在Linux下还是Windows下都有问题. 1.linux下我用gcc编译,代码中就直接写了个#include "zlib.h",然后就可以用compress和uncompress函数了,可是我的问题是要用来解压Zip文件啊,并不是压缩字符串,然后就用miniZip文件夹中的zip.h和unzip.h,include到代码中,结果调用里面

ant包解压zip文件。。。。求助。。。。。

问题描述 ant-1.7.1.jar我想指定解压zip包里的文件夹.不要全部解压.请问谁有ant包的帮助文档...求助........ 解决方案 解决方案二:怎么获取zip包里所有的文件夹名称,然后执行遍历解压?解决方案三:http://wenku.baidu.com/view/f56b990d4a7302768e993999.html不知道这个行不行,回头帮你找哈.为什么你自己不去找找呀解决方案四:比如说一个zip包中有10个文件夹遍历出后,我只取其中一个解压到指定的目录..解决方案五:这个真

python解决Fedora解压zip时中文乱码的方法_python

前言 很多时候在windows下压缩文件没问题,但是到了Linux下,出现乱码,很常见.以前在Ubuntu下,用`unzip -O GBK filename.zip` 就可以搞定. 换了Fedora后,暂时没发现乱码的压缩文件.晚上下载一本书的光盘,又碰到了乱码.尝试之前的方法没成功.看了下unzip的help,没-O那个参数了== 刚好找到一个用python解决的办法,分享下. 新建一个`.py`后缀的文件,直接复制粘贴代码: #!/usr/bin/env python # -*- codin

关于解压ZIP的问题

问题描述 假如我有一个ZIP文件是在另外一台服务器上,知道这个文件的完整路径,是否可以对它进行在线解压? 解决方案 本帖最后由 aa258378001 于 2014-12-01 18:06:40 编辑解决方案二:没权限啊.都知道路径了,为什么不下载来解压?解决方案三:如果是ftp并且有写的权限就可以,如果是局域网并且有可写权限的共享账号和密码就可以,如果就是个http你可以开个接口出来请求接口传入参数解压指定路径如果只是一个http当然不能,这就跟有人问浏览器可不可以直接执行1个可执行程序一样解

PHP 的解压缩ZipArchive中的extractTo()方法 LINUX+nginx环境中解压zip时文件丢失的问题

    在项目中要用ZipArchive解压ZIP文件,起初测试环境在WINDOWS平台中,测试通过,换到 LINUX+nginx 的环境中时 就出问题了(ZIP包中有文件和文件夹一共3百多个文件,大部分是带汉字的文件名),问题的现象是:不带汉字的文件解压没有问题,另外有部分带汉字和数字字母的文件解压没有问题,然后其他纯文字的文件名就丢失了,也没有报错,最后把问题定位到了extractTo()方法,这个方法尼玛是个封装的方法,看不到实际的源代码.       但是,发现 for($i = 0;

解压zip压缩包中的指定文件(害死人的错误)

使用Java 解压zip压缩包中的指定文件时遇到了问题. 且听我细细道来: 主要方法如下: Java代码   public static byte[] getContent2(final ZipFile zipFile, final ZipEntry zipEntry)               throws IOException {           InputStream inputStream = zipFile.getInputStream(zipEntry);          

支持中文Java压缩与解压zip文件程序代码

apache ant下载地址: http://ant.apache.org/bindownload.cgi 把lib/ant.jar放到我们项目的构建路径中,只需要ant.jar.其实ant的zip API与jdk的高度相似,如果之前是用jdk的api写的,基本上只要更改顶部的import包就可以了  代码如下 复制代码 package common;   import java.io.BufferedInputStream; import java.io.BufferedOutputStrea