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 和 MySQL 开发的 8 个技巧
Oct 09 PHP
php 远程关机操作的代码
Dec 05 PHP
php class中self,parent,this的区别以及实例介绍
Apr 24 PHP
php解析url的三个示例
Jan 20 PHP
单台服务器的PHP进程之间实现共享内存的方法
Jun 13 PHP
PHP向socket服务器收发数据的方法
Jan 24 PHP
PHP实现多文件上传的方法
Jul 08 PHP
thinkphp,onethink和thinkox中验证码不显示的解决方法分析
Jun 06 PHP
php的socket编程详解
Nov 20 PHP
Laravel 5.5基于内置的Auth模块实现前后台登陆详解
Dec 21 PHP
PHP 枚举类型的管理与设计知识点总结
Feb 13 PHP
如何用PHP websocket实现网页实时聊天
May 26 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
DOTA2【瓜皮时刻】Vol.91 RTZ山史最惨“矿难”
2021/03/05 DOTA
Get或Post提交值的非法数据处理
2006/10/09 PHP
解析php curl_setopt 函数的相关应用及介绍
2013/06/17 PHP
PHP使用递归方式列出当前目录下所有文件的方法
2015/06/02 PHP
分享php邮件管理器源码
2016/01/06 PHP
laravel自定义分页效果
2017/07/23 PHP
JavaScript 权威指南(第四版) 读书笔记
2009/08/11 Javascript
基于JavaScript 类的使用详解
2013/05/07 Javascript
jquery操作select大全
2014/04/25 Javascript
详解微信小程序开发之——wx.showToast(OBJECT)的使用
2017/01/18 Javascript
canvas 实现中国象棋
2017/02/17 Javascript
使用JavaScript进行表单校验功能
2017/08/01 Javascript
JavaScript闭包和回调详解
2017/08/09 Javascript
Vue完整项目构建(进阶篇)
2018/02/10 Javascript
Vue render渲染时间戳转时间,时间转时间戳及渲染进度条效果
2018/07/27 Javascript
实例详解vue.js浅度监听和深度监听及watch用法
2018/08/16 Javascript
详解如何构建Promise队列实现异步函数顺序执行
2018/10/23 Javascript
Javascript中弹窗confirm与prompt的区别
2018/10/26 Javascript
js+canvas实现画板功能
2020/09/13 Javascript
Python使用设计模式中的责任链模式与迭代器模式的示例
2016/03/02 Python
解决pyqt中ui编译成窗体.py中文乱码的问题
2016/12/23 Python
Python编程实现数学运算求一元二次方程的实根算法示例
2017/04/02 Python
python模块之sys模块和序列化模块(实例讲解)
2017/09/13 Python
python爬虫之线程池和进程池功能与用法详解
2018/08/02 Python
opencv python 图像去噪的实现方法
2018/08/31 Python
Python中的random.uniform()函数教程与实例解析
2019/03/02 Python
简单了解Django ContentType内置组件
2019/07/23 Python
python 浮点数四舍五入需要注意的地方
2020/08/18 Python
澳大利亚一站式数码相机商店:CameraPro
2020/03/09 全球购物
接口中的方法可以是abstract的吗
2015/07/23 面试题
小学岗位竞聘方案
2014/01/22 职场文书
人口与计划生育目标管理责任书
2014/07/29 职场文书
初中毕业典礼演讲稿
2014/09/09 职场文书
工地材料员岗位职责
2015/04/11 职场文书
2015年施工员工作总结范文
2015/04/20 职场文书
Python极值整数的边界探讨分析
2021/09/15 Python