php zip文件解压类代码


Posted in PHP onDecember 02, 2009
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\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; 
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.$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; 
} 
} 
/***********************************/ 
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; 
        } 
    } 
    /** 
     * 检查目录是否存在,如果不存在是否建立 
     * 
     * @param string $dirname        完整的实际路径 
     * @param bool $mk                如果不存在是否创建 
     * @param int $mode                创建权限 
     * @return bool                    是否创建成功 
     */ 
    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<count($dirpath_a);$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); 
//要解压的文件路径 
$arch = $_GET["arch"]; 
if(!$arch || !file_exists($arch)) 
$z = new Zip; 
$l=$z->get_list($arch); //得到文件列表 
$z->Extract($arch, "jieya", -1 ); 
}
PHP 相关文章推荐
请php正则走开
Mar 15 PHP
php实现简单洗牌算法
Jun 18 PHP
php echo, print, print_r, sprintf, var_dump, var_expor的使用区别
Jun 20 PHP
解析php中的escape函数
Jun 29 PHP
一漂亮的PHP图片验证码实例
Mar 21 PHP
PHP中使用imagick实现把PDF转成图片
Jan 26 PHP
PHP使用MPDF类生成PDF的方法
Dec 08 PHP
深入浅析PHP的session反序列化漏洞问题
Jun 15 PHP
PHP编程中的Session阻塞问题与解决方法分析
Aug 07 PHP
学习thinkphp5.0验证类使用方法
Nov 16 PHP
PHP实现打包zip并下载功能
Jun 12 PHP
php桥接模式应用案例分析
Oct 23 PHP
PHP5 面向对象(学习记录)
Dec 02 #PHP
php smarty模版引擎中的缓存应用
Dec 02 #PHP
php 一元分词算法
Nov 30 #PHP
PHP MYSQL乱码问题,使用SET NAMES utf8校正
Nov 30 #PHP
php读取html并截取字符串的简单代码
Nov 30 #PHP
php 获取客户端的真实ip
Nov 30 #PHP
php操作sqlserver关于时间日期读取的小小见解
Nov 29 #PHP
You might like
Bootstrap+PHP实现多图上传功能实例详解
2018/04/08 PHP
javascript中删除指定数组中指定的元素的代码
2011/02/12 Javascript
用jquery存取照片的具体实现方法
2013/06/30 Javascript
解决Extjs4中form表单提交后无法进入success函数问题
2013/11/26 Javascript
js在输入框屏蔽按键,只能键入数字的示例代码
2014/01/03 Javascript
jquery ajax跨域解决方法(json方式)
2014/02/04 Javascript
jquery实现点击文字可编辑并修改保存至数据库
2014/04/15 Javascript
JS 日期与时间戮相互转化的简单实例
2016/06/22 Javascript
字太多用...代替的方法(两种)
2017/03/15 Javascript
解决select2在bootstrap modal中不能正常使用的问题
2018/08/09 Javascript
js监听html页面的上下滚动事件方法
2018/09/11 Javascript
vue图片上传本地预览组件使用详解
2019/02/20 Javascript
微信小程序实现文件、图片上传功能
2020/08/18 Javascript
vue 出现data-v-xxx的原因及解决
2020/08/04 Javascript
Python 调用VC++的动态链接库(DLL)
2008/09/06 Python
tornado框架blog模块分析与使用
2013/11/21 Python
Python常用知识点汇总
2016/05/08 Python
Django框架之中间件MiddleWare的实现
2019/12/30 Python
PyQt5实现仿QQ贴边隐藏功能的实例代码
2020/05/24 Python
零基础学python应该从哪里入手
2020/08/11 Python
记一次Django响应超慢的解决过程
2020/09/17 Python
python爬虫分布式获取数据的实例方法
2020/11/26 Python
一家专门做特卖的网站:唯品会
2016/10/09 全球购物
美国健康和保健平台:healtop
2020/07/02 全球购物
编程输出如下图形
2013/11/24 面试题
考试不及格检讨书
2014/01/09 职场文书
会计专业求职信范文
2014/03/16 职场文书
护理专业自荐书
2014/06/04 职场文书
2014单位领导班子四风对照检查材料思想汇报
2014/09/25 职场文书
工作表扬信范文
2015/01/17 职场文书
委托书的样本
2015/01/28 职场文书
2015医德医风个人工作总结
2015/04/02 职场文书
2016年推广普通话宣传周活动总结
2016/04/06 职场文书
python实现剪贴板的操作
2021/07/01 Python
python 中的jieba分词库
2021/11/23 Python
nginx之queue的具体使用
2022/06/28 Servers