<?php

/**
* Created by PhpStorm.
* User: StarZhan
* Date: 2016/5/24
* Time: 12:04
*/
class PHPZip
{
private $ctrl_dir = array();
private $datasec = array(); /**********************************************************
* 压缩部分
**********************************************************/
// ------------------------------------------------------ //
// #遍历指定文件夹
//
// $archive = new PHPZip();
// $filelist = $archive->visitFile(文件夹路径);
// print "当前文件夹的文件:<p>\r\n";
// foreach($filelist as $file)
// printf("%s<br>\r\n", $file);
// ------------------------------------------------------ //
var $fileList = array(); public function visitFile($path)
{
global $fileList;
$path = str_replace("\\", "/", $path);
$fdir = dir($path); while (($file = $fdir->read()) !== false) {
if ($file == '.' || $file == '..') {
continue;
} $pathSub = preg_replace("*/{2,}*", "/", $path . "/" . $file); // 替换多个反斜杠
$fileList[] = is_dir($pathSub) ? $pathSub . "/" : $pathSub;
if (is_dir($pathSub)) {
$this->visitFile($pathSub);
}
}
$fdir->close();
return $fileList;
} private function unix2DosTime($unixtime = 0)
{
$timearray = ($unixtime == 0) ? getdate() : getdate($unixtime); 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);
} var $old_offset = 0; private function addFile($data, $filename, $time = 0)
{
$filename = str_replace('\\', '/', $filename); $dtime = dechex($this->unix2DosTime($time));
$hexdtime = '\x' . $dtime[6] . $dtime[7]
. '\x' . $dtime[4] . $dtime[5]
. '\x' . $dtime[2] . $dtime[3]
. '\x' . $dtime[0] . $dtime[1];
eval('$hexdtime = "' . $hexdtime . '";'); $fr = "\x50\x4b\x03\x04";
$fr .= "\x14\x00";
$fr .= "\x00\x00";
$fr .= "\x08\x00";
$fr .= $hexdtime;
$unc_len = strlen($data);
$crc = crc32($data);
$zdata = gzcompress($data);
$c_len = strlen($zdata);
$zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);
$fr .= pack('V', $crc);
$fr .= pack('V', $c_len);
$fr .= pack('V', $unc_len);
$fr .= pack('v', strlen($filename));
$fr .= pack('v', 0);
$fr .= $filename; $fr .= $zdata; $fr .= pack('V', $crc);
$fr .= pack('V', $c_len);
$fr .= pack('V', $unc_len); $this->datasec[] = $fr;
$new_offset = strlen(implode('', $this->datasec)); $cdrec = "\x50\x4b\x01\x02";
$cdrec .= "\x00\x00";
$cdrec .= "\x14\x00";
$cdrec .= "\x00\x00";
$cdrec .= "\x08\x00";
$cdrec .= $hexdtime;
$cdrec .= pack('V', $crc);
$cdrec .= pack('V', $c_len);
$cdrec .= pack('V', $unc_len);
$cdrec .= pack('v', strlen($filename));
$cdrec .= pack('v', 0);
$cdrec .= pack('v', 0);
$cdrec .= pack('v', 0);
$cdrec .= pack('v', 0);
$cdrec .= pack('V', 32); $cdrec .= pack('V', $this->old_offset);
$this->old_offset = $new_offset; $cdrec .= $filename;
$this->ctrl_dir[] = $cdrec;
} var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; private function 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";
} // ------------------------------------------------------ //
// #压缩到服务器
//
// $archive = new PHPZip();
// $archive->Zip("需压缩的文件所在目录", "ZIP压缩文件名");
// ------------------------------------------------------ //
public function Zip($dir, $saveName)
{
if (@!function_exists('gzcompress')) {
return;
} ob_end_clean();
$filelist = $this->visitFile($dir);
if (count($filelist) == 0) {
return;
} foreach ($filelist as $file) {
if (!file_exists($file) || !is_file($file)) {
continue;
} $fd = fopen($file, "rb");
$content = @fread($fd, filesize($file));
fclose($fd); // 1.删除$dir的字符(./folder/file.txt删除./folder/)
// 2.如果存在/就删除(/file.txt删除/)
$file = substr($file, strlen($dir));
if (substr($file, 0, 1) == "\\" || substr($file, 0, 1) == "/") {
$file = substr($file, 1);
} $this->addFile($content, $file);
}
$out = $this->file(); $fp = fopen($saveName, "wb");
fwrite($fp, $out, strlen($out));
fclose($fp);
} // ------------------------------------------------------ //
// #压缩并直接下载
//
// $archive = new PHPZip();
// $archive->ZipAndDownload("需压缩的文件所在目录");
// ------------------------------------------------------ //
public function ZipAndDownload($filelist, $fileName = "网申资料")
{
if (@!function_exists('gzcompress')) {
return;
} ob_end_clean();
//$filelist = $this->visitFile($dir);
if (count($filelist) == 0) {
return;
} foreach ($filelist as $fileinfo) {
$info = $fileinfo['name'];
$file = $fileinfo['path'];
if (!file_exists($file) || !is_file($file)) {
continue;
} $fd = fopen($file, "rb");
$content = @fread($fd, filesize($file));
fclose($fd); // 1.删除$dir的字符(./folder/file.txt删除./folder/)
// 2.如果存在/就删除(/file.txt删除/)
$tmpfile = explode('/', $file);
$file = end($tmpfile);
$tmpext = explode('.', $file);
$ext = end($tmpext);
// if (substr($file, 0, 1) == "\\" || substr($file, 0, 1) == "/") {
// $file = substr($file, 1);
// }
$info = iconv("UTF-8", "GBK", $info);
$file = $info . "." . $ext;
$this->addFile($content, $file);
}
$out = $this->file(); @header('Content-Encoding: none');
@header('Content-Type: application/zip');
@header('Content-Disposition: attachment ; filename=' . $fileName . date("YmdHis", time()) . '.zip');
@header('Pragma: no-cache');
@header('Expires: 0');
print($out);
} /**********************************************************
* 解压部分
**********************************************************/
// ------------------------------------------------------ //
// ReadCentralDir($zip, $zipfile)
// $zip是经过@fopen($zipfile, 'rb')打开的
// $zipfile是zip文件的路径
// ------------------------------------------------------ //
private
function ReadCentralDir($zip, $zipfile)
{
$size = filesize($zipfile);
$max_size = ($size < 277) ? $size : 277; @fseek($zip, $size - $max_size);
$pos = ftell($zip);
$bytes = 0x00000000; while ($pos < $size) {
$byte = @fread($zip, 1);
$bytes = ($bytes << 8) | Ord($byte);
$pos++;
if ($bytes == 0x504b0506) {
break;
}
} $data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', fread($zip, 18)); $centd['comment'] = ($data['comment_size'] != 0) ? fread($zip, $data['comment_size']) : ''; // 注释
$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;
} private
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); $header['filename'] = ($header['filename_len'] != 0) ? fread($zip, $header['filename_len']) : '';
$header['extra'] = ($header['extra_len'] != 0) ? fread($zip, $header['extra_len']) : '';
$header['comment'] = ($header['comment_len'] != 0) ? fread($zip, $header['comment_len']) : ''; 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;
} private 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']);
$header['extra'] = ($data['extra_len'] != 0) ? fread($zip, $data['extra_len']) : '';
$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;
} private function ExtractFile($header, $to, $zip)
{
$header = $this->readfileheader($zip); if (substr($to, -1) != "/") {
$to .= "/";
}
if (!@is_dir($to)) {
@mkdir($to, 0777);
}
$pthss = '';
$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;
} // ------------------------------------------------------ //
// #解压文件
//
// $archive = new PHPZip();
// $zipfile = "ZIP压缩文件名";
// $savepath = "解压缩目录名";
// $zipfile = $unzipfile;
// $savepath = $unziptarget;
// $array = $archive->GetZipInnerFilesInfo($zipfile);
// $filecount = 0;
// $dircount = 0;
// $failfiles = array();
// set_time_limit(0); // 修改为不限制超时时间(默认为30秒)
//
// for($i=0; $i<count($array); $i++) {
// if($array[$i][folder] == 0){
// if($archive->unZip($zipfile, $savepath, $i) > 0){
// $filecount++;
// }else{
// $failfiles[] = $array[$i][filename];
// }
// }else{
// $dircount++;
// }
// }
// set_time_limit(30);
//printf("文件夹:%d&nbsp;&nbsp;&nbsp;&nbsp;解压文件:%d&nbsp;&nbsp;&nbsp;&nbsp;失败:%d<br>\r\n", $dircount, $filecount, count($failfiles));
//if(count($failfiles) > 0){
// foreach($failfiles as $file){
// printf("&middot;%s<br>\r\n", $file);
// }
//}
// ------------------------------------------------------ //
public function unZip($zipfile, $to, $index = Array(-1))
{
$ok = 0;
$zip = @fopen($zipfile, 'rb');
if (!$zip) {
return (-1);
} $cdir = $this->ReadCentralDir($zip, $zipfile);
$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;
} /**********************************************************
* 其它部分
**********************************************************/
// ------------------------------------------------------ //
// #获取被压缩文件的信息
//
// $archive = new PHPZip();
// $array = $archive->GetZipInnerFilesInfo(ZIP压缩文件名);
// for($i=0; $i<count($array); $i++) {
// printf("<b>&middot;%s</b><br>\r\n", $array[$i][filename]);
// foreach($array[$i] as $key => $value)
// printf("%s => %s<br>\r\n", $key, $value);
// print "\r\n<p>------------------------------------<p>\r\n\r\n";
// }
// ------------------------------------------------------ //
public function GetZipInnerFilesInfo($zipfile)
{
$zip = @fopen($zipfile, 'rb');
if (!$zip) {
return (0);
}
$centd = $this->ReadCentralDir($zip, $zipfile); @rewind($zip);
@fseek($zip, $centd['offset']);
$ret = array(); for ($i = 0; $i < $centd['entries']; $i++) {
$header = $this->ReadCentralFileHeaders($zip);
$header['index'] = $i;
$info = array(
'filename' => $header['filename'], // 文件名
'stored_filename' => $header['stored_filename'], // 压缩后文件名
'size' => $header['size'], // 大小
'compressed_size' => $header['compressed_size'], // 压缩后大小
'crc' => strtoupper(dechex($header['crc'])), // CRC32
'mtime' => date("Y-m-d H:i:s", $header['mtime']), // 文件修改时间
'comment' => $header['comment'], // 注释
'folder' => ($header['external'] == 0x41FF0010 || $header['external'] == 16) ? 1 : 0, // 是否为文件夹
'index' => $header['index'], // 文件索引
'status' => $header['status'] // 状态
);
$ret[] = $info;
unset($header);
}
fclose($zip);
return $ret;
} // ------------------------------------------------------ //
// #获取压缩文件的注释
//
// $archive = new PHPZip();
// echo $archive->GetZipComment(ZIP压缩文件名);
// ------------------------------------------------------ //
public function GetZipComment($zipfile)
{
$zip = @fopen($zipfile, 'rb');
if (!$zip) {
return (0);
}
$centd = $this->ReadCentralDir($zip, $zipfile);
fclose($zip);
return $centd[comment];
}
} 调用方法

												

php_zip 类的更多相关文章

  1. Java类的继承与多态特性-入门笔记

    相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...

  2. PHP扩展类ZipArchive实现压缩解压Zip文件和文件打包下载 && Linux下的ZipArchive配置开启压缩 &&搞个鸡巴毛,写少了个‘/’号,浪费了一天

    PHP ZipArchive 是PHP自带的扩展类,可以轻松实现ZIP文件的压缩和解压,使用前首先要确保PHP ZIP 扩展已经开启,具体开启方法就不说了,不同的平台开启PHP扩增的方法网上都有,如有 ...

  3. C++ 可配置的类工厂

    项目中常用到工厂模式,工厂模式可以把创建对象的具体细节封装到Create函数中,减少重复代码,增强可读和可维护性.传统的工厂实现如下: class Widget { public: virtual i ...

  4. Android请求网络共通类——Hi_博客 Android App 开发笔记

    今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. ...

  5. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

    在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...

  6. ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core

    背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...

  7. .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类

    .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件.除 ...

  8. Java基础Map接口+Collections工具类

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  9. PHP-解析验证码类--学习笔记

    1.开始 在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下. 2.类图 3.验证码类部分代码 3.1  定义变量 //随机因子 private $char ...

随机推荐

  1. Oracle时间戳(毫秒)转为Date

    1.SQL ) + TO_DATE('1970-01-01 08:00:00', 'YYYY-MM-DD HH:MI:SS'), 'YYYY-MM-DD HH:MI:SS') AS CDATE FRO ...

  2. VPS服务商

    1.vpsee http://www.vpsee.com 2.vps侦探 http://www.vpser.net/

  3. 每天一个 Linux 命令(21):find命令之xargs

    在使用 find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行.但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出 ...

  4. 翻书插件:bookblock.js

    BookBlock 是一个 jQuery插件,用来制作带有翻页效果的小书册.可以用任何形式的内容,比如图像或文本.插件会在翻页时利用变形模拟手工翻页,并产生重叠的阴影以达到更逼真的效果. 基本页面 & ...

  5. MongoDB【第三篇】MongoDB基本操作

    MongoDB的基本操作包括文档的创建.删除.和更新 文档插入 1.插入 #查看当前都有哪些数据库 > show dbs; local 0.000GB tim 0.000GB #使用 tim数据 ...

  6. 微软压力测试工具 web application stress

    转自 http://www.cnblogs.com/tonykan/p/3514749.html lbimba  铜牌会员 这里给广大的煤油推荐一个web网站压力测试工具.它可以用来模拟多个用户操作网 ...

  7. [整理]AngularJS移动端开发遇到的问题

    最近在开发一个移动WebAPP的小项目,因为之前一直使用AngularJS, 对于这个项目,废话不多说,拿过来就用上了. 开发过程是一路通畅和舒服的,但是,却忽略了一个非常重要的问题,移动2G环境下的 ...

  8. mysql存储过程和存储函数

    mysql存储过程和存储函数 存数函数代码示例: DROP PROCEDURE IF EXISTS calc_ci_day_suc_rate; delimiter // CREATE FUNCTION ...

  9. SQL Server数据库定时自动备份

    SQL Server 数据库定时自动备份[转]   在SQL Server中出于数据安全的考虑,所以需要定期的备份数据库.而备份数据库一般又是在凌晨时间基本没有数据库操作的时候进行,所以我们不可能要求 ...

  10. Subsonic使用中

    使用中,遇到各种奇葩问题,依依汇总. 1.引用了Subsonic层后,一运行就开始报错,提示未能找到文件!!    //引用后,目标框架可能会被改变,subsonic的默认框架是2.0,请检查框架是否 ...