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 相关文章推荐
首页四格,首页五格For6.0(GBK)(UTF-8)[12种组合][9-18][版主安装测试通过]
Sep 24 PHP
php 数组二分法查找函数代码
Feb 16 PHP
让php处理图片变得简单 基于gb库的图片处理类附实例代码下载
May 17 PHP
PHP中将网页导出为Word文档的代码
May 25 PHP
php上传图片存入数据库示例分享
Mar 11 PHP
PHP中auto_prepend_file与auto_append_file用法实例分析
Sep 22 PHP
php实现的IMEI限制的短信验证码发送类
May 05 PHP
基于PHP实现数据分页显示功能
May 26 PHP
thinkphp在低版本Nginx 下支持PATHINFO的方法分享
May 27 PHP
PHP中strpos、strstr和stripos、stristr函数分析
Jun 11 PHP
PHP 7安装使用体验之性能大提升,兼容性强,扩展支持不够(升级PHP要谨慎)
Jul 27 PHP
PHP连接SQL server数据库测试脚本运行实例
Aug 24 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
PHP中文URL编解码(urlencode()rawurlencode()
2010/07/03 PHP
简单介绍PHP非阻塞模式
2016/03/03 PHP
Javascript基础教程之数据类型 (布尔型 Boolean)
2015/01/18 Javascript
JavaScript插件化开发教程 (四)
2015/01/27 Javascript
js实现checkbox全选、不选与反选的方法
2015/02/09 Javascript
javascript限制文本框输入值类型的方法
2015/05/07 Javascript
jQuery同步提交示例代码
2015/12/12 Javascript
Bootstrap布局组件教程之Bootstrap下拉菜单
2016/06/12 Javascript
AngularJS实现页面定时刷新
2017/03/14 Javascript
Vue.js使用$.ajax和vue-resource实现OAuth的注册、登录、注销和API调用
2017/05/10 Javascript
VSCode 配置React Native开发环境的方法
2017/12/27 Javascript
react router4+redux实现路由权限控制的方法
2018/05/03 Javascript
详解vue-loader在项目中是如何配置的
2018/06/04 Javascript
Windows下安装python2和python3多版本教程
2017/03/30 Python
Python字符串和字典相关操作的实例详解
2017/09/23 Python
python如何让类支持比较运算
2018/03/20 Python
PyTorch 1.0 正式版已经发布了
2018/12/13 Python
Python多线程正确用法实例解析
2020/05/30 Python
浅谈TensorFlow之稀疏张量表示
2020/06/30 Python
Python定时任务框架APScheduler原理及常用代码
2020/10/05 Python
CSS3 新增选择器的实例
2019/11/13 HTML / CSS
阿联酋航空官方网站:Emirates
2017/10/17 全球购物
yy婚礼主持词
2014/03/14 职场文书
承诺书的格式范文
2014/03/28 职场文书
初中教师业务学习材料
2014/05/12 职场文书
我爱我校演讲稿
2014/05/21 职场文书
119消防日活动总结
2014/08/29 职场文书
学院党的群众路线教育实践活动第一阶段情况汇报
2014/10/25 职场文书
任命书怎么写
2015/03/02 职场文书
医院合作意向书范本
2015/05/08 职场文书
单方投资意向书
2015/05/11 职场文书
2015年社区教育工作总结
2015/05/13 职场文书
2016党员干部反腐倡廉心得体会
2016/01/13 职场文书
Vue3 Composition API的使用简介
2021/03/29 Vue.js
用Python简陋模拟n阶魔方
2021/04/17 Python
Python数据可视化之基于pyecharts实现的地理图表的绘制
2021/06/10 Python