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的面试题集,附我的答案和分析(一)
Nov 19 PHP
PHP 采集获取指定网址的内容
Jan 05 PHP
php下连接mssql2005的代码
Jan 17 PHP
PHP无限分类代码,支持数组格式化、直接输出菜单两种方式
May 18 PHP
php检测图片木马多进制编程实践
Apr 11 PHP
php缓冲 output_buffering的使用详解
Jun 13 PHP
php截取字符串之截取utf8或gbk编码的中英文字符串示例
Mar 12 PHP
浅析get与post的一些特殊情况
Jul 28 PHP
百度工程师讲PHP函数的实现原理及性能分析(二)
May 13 PHP
php curl模拟post请求和提交多维数组的示例代码
Nov 19 PHP
详解PHP使用Redis存储session时的一个Warning定位
Jul 05 PHP
Laravel 之url参数,获取路由参数的例子
Oct 21 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
destoon调用discuz论坛中带图片帖子的实现方法
2014/08/21 PHP
php使用curl获取https请求的方法
2015/02/11 PHP
使用PHP+AJAX让WordPress动态加载文章的教程
2015/12/11 PHP
php制作圆形用户头像的实例_自定义封装类源代码
2017/09/18 PHP
PHP实现简单计算器小程序
2020/08/28 PHP
jquery 新手学习常见问题解决方法
2010/04/18 Javascript
关于COOKIE个数与大小的问题
2011/01/17 Javascript
jQuery中的.bind()、.live()和.delegate()之间区别分析
2011/06/08 Javascript
在HTML代码中使用JavaScript代码的例子
2014/10/16 Javascript
分享9个最好用的JavaScript开发工具和代码编辑器
2015/03/24 Javascript
javascript中offset、client、scroll的属性总结
2015/08/13 Javascript
整理JavaScript对DOM中各种类型的元素的常用操作
2016/05/05 Javascript
点击页面任何位置隐藏div的实现方法
2016/09/05 Javascript
使用jquery.qrcode.js生成二维码插件
2016/10/17 Javascript
详解Vue结合后台的列表增删改案例
2018/08/21 Javascript
vue cli3 配置proxy代理无效的解决
2019/10/30 Javascript
Python中实现两个字典(dict)合并的方法
2014/09/23 Python
Python3遍历目录树实现方法
2015/05/22 Python
Python+OpenCV人脸检测原理及示例详解
2020/10/19 Python
pandas 获取季度,月度,年度首尾日期的方法
2018/04/11 Python
使用Python和xlwt向Excel文件中写入中文的实例
2018/04/21 Python
简单了解pytest测试框架setup和tearDown
2020/04/14 Python
python中的垃圾回收(GC)机制
2020/09/21 Python
Python使用for生成列表实现过程解析
2020/09/22 Python
Python+OpenCV检测灯光亮点的实现方法
2020/11/02 Python
聊聊python在linux下与windows下导入模块的区别说明
2021/03/03 Python
介绍一下SQL Server的全文索引
2013/08/15 面试题
自我评价的写作规则
2014/01/06 职场文书
优秀交警事迹材料
2014/01/26 职场文书
法律进社区实施方案
2014/03/21 职场文书
年终晚会主持词
2014/03/25 职场文书
文明村创建实施方案
2014/03/27 职场文书
《窗前的气球》教学反思
2014/04/07 职场文书
车辆年检委托书范本
2014/10/14 职场文书
初中优秀学生评语
2014/12/29 职场文书
人生遥控器观后感
2015/06/11 职场文书