php生成zip压缩文件的方法详解


Posted in PHP onJune 09, 2013
require_once "./include/zip.php"; 
$zip = new PHPZip(); 
//$zip -> createZip("要压缩的文件夹目录地址", "压缩后的文件名.zip"); //只生成不自动下载 
$zip -> downloadZip("要压缩的文件夹目录地址", "压缩后的文件名.zip");
//自动下载

实例:可以参考下面的伪代码来看一个具体的使用场景:
代码
require_once "./include/zip.php"; 
if (!$download) { 
exit(); 
} 
set_time_limit(60); 
$tmpManager = new TmpManager(); //假设我们有一个类来完成后面的操作 
$tempfolder = array(); 
$tempfile = array(); 
//假设我们是通过在页面上选择checkbox来下载已选的文件夹或文件,并一同打包 
for($i = 0;$i < $checkboxnum;$i++) { 
$value = ${"select".$i}; 
if ($value != '') { 
$this_type = substr($value, 0, 1); 
$this_id = substr($value, 1); 
//将文件夹和文件的情况分开处理 
if ($this_type == 'd') { 
$tempfolder[] = $this_id; 
} 
elseif ($this_type == 'f') { 
$tempfile[] = $this_id; 
} 
} 
} 
@mkdir($tempdir); 
$curtempdir = "$tempdir/".$userid; //不同用户在不同的临时文件夹下操作 
if (file_exists($curtempdir)) { 
$tmpManager->DeleteDir($curtempdir); //删除旧的文件夹 
} 
if (sizeof($tempfolder) > 0 || sizeof($tempfile) > 0) { 
mkdir($curtempdir, 0777); //如果有要打包的文件货文件夹,重新创建文件夹 
} 
if (sizeof($tempfile) > 0) { 
$tmpManager->CopyFile($tempfile,$curtempdir); //将要下载的文件copy到创建的文件夹 
} 
if (sizeof($tempfolder) > 0) { 
$tmpManager->CopyFolder($tempfolder,$curtempdir); //将要下载的文件夹copy到创建的文件夹 
} 
$zip = new PHPZip(); 
$zip -> downloadZip($curtempdir, "file_".date('Ymd').".zip"); //打包并下载

zip.php
<?php 
/* 
File name: /include/zip.php 
Author: Horace 2009/04/15 
*/ 
class PHPZip{ 
var $dirInfo = array("0","0"); 
var $rootDir = ''; 
var $datasec = array(); 
var $ctrl_dir = array(); 
var $eof_ctrl_dir = "/x50/x4b/x05/x06/x00/x00/x00/x00"; 
var $old_offset = 0; 
function downloadZip(){ 
createZip($dir, $zipfilename, true); 
} 
function createZip($dir, $zipfilename, $autoDownload = false){ 
if (@function_exists('gzcompress')){ 
@set_time_limit("0"); 
if (is_array($dir)){ 
$fd = fopen ($dir, "r"); 
$fileValue = fread ($fd, filesize ($filename)); 
fclose ($fd); 
if (is_array($dir)) $filename = basename($dir); 
$this -> addFile($fileValue, "$filename"); 
}else{ 
$this->dirTree($dir,$dir); 
} 
$zipfilenametemp = time().$zipfilename; 
$out = $this -> filezip(); 
$fp = fopen($zipfilenametemp, "w"); 
fwrite($fp, $out, strlen($out)); 
fclose($fp); 
$filesize = filesize($zipfilenametemp); 
if ($filesize < 104857600) { 
if($autoDownload){ 
header("Content-type: application/octet-stream"); 
header("Content-disposition: attachment; filename=".$zipfilename); 
} 
echo $this -> filezip(); 
}else{ 
echo "create zip error!"; 
} 
unlink($zipfilenametemp); 
} 
} 
//get dir tree.. 
function dirTree($directory,$rootDir){ 
global $_SERVER,$dirInfo,$rootDir; 
$fileDir=$rootDir; 
$myDir=dir($directory); 
while($file=$myDir->read()){ 
if(is_dir("$directory/$file") and $file!="." and $file!=".."){ 
$dirInfo[0]++; 
$rootDir ="$fileDir$file/"; 
$this -> addFile('', "$rootDir"); 
//go on n's folders 
$this->dirTree("$directory/$file",$rootDir); 
}else{ 
if($file!="." and $file!=".."){ 
$dirInfo[1]++; 
//$fd = fopen ("$directory/$file", "r"); 
$fileValue = file_get_contents("$directory/$file"); 
//fclose ($fd); 
$this -> addFile($fileValue, "$fileDir$file"); 
} 
} 
} 
$myDir->close(); 
} 
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; 
} // end if 
return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | 
($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1); 
} 
function addFile($data, $name, $time = 0){ 
$name = str_replace('//', '/', $name); 
$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"; // ver needed to extract 
$fr .= "/x00/x00"; // gen purpose bit flag 
$fr .= "/x08/x00"; // compression method 
$fr .= $hexdtime; // last mod time and date 
// "local file header" segment 
$unc_len = strlen($data); 
$crc = crc32($data); 
$zdata = gzcompress($data); 
$c_len = strlen($zdata); 
$zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug 
$fr .= pack('V', $crc); // crc32 
$fr .= pack('V', $c_len); // compressed filesize 
$fr .= pack('V', $unc_len); // uncompressed filesize 
$fr .= pack('v', strlen($name)); // length of filename 
$fr .= pack('v', 0); // extra field length 
$fr .= $name; 
// "file data" segment 
$fr .= $zdata; 
// "data descriptor" segment (optional but necessary if archive is not 
// served as file) 
$fr .= pack('V', $crc); // crc32 
$fr .= pack('V', $c_len); // compressed filesize 
$fr .= pack('V', $unc_len); // uncompressed filesize 
// add this entry to array 
$this -> datasec[] = $fr; 
$new_offset = strlen(implode('', $this->datasec)); 
// now add to central directory record 
$cdrec = "/x50/x4b/x01/x02"; 
$cdrec .= "/x00/x00"; // version made by 
$cdrec .= "/x14/x00"; // version needed to extract 
$cdrec .= "/x00/x00"; // gen purpose bit flag 
$cdrec .= "/x08/x00"; // compression method 
$cdrec .= $hexdtime; // last mod time & date 
$cdrec .= pack('V', $crc); // crc32 
$cdrec .= pack('V', $c_len); // compressed filesize 
$cdrec .= pack('V', $unc_len); // uncompressed filesize 
$cdrec .= pack('v', strlen($name) ); // length of filename 
$cdrec .= pack('v', 0 ); // extra field length 
$cdrec .= pack('v', 0 ); // file comment length 
$cdrec .= pack('v', 0 ); // disk number start 
$cdrec .= pack('v', 0 ); // internal file attributes 
$cdrec .= pack('V', 32 ); // external file attributes - 'archive' bit set 
$cdrec .= pack('V', $this -> old_offset ); // relative offset of local header 
$this -> old_offset = $new_offset; 
$cdrec .= $name; 
// optional extra field, file comment goes here 
// save to central directory 
$this -> ctrl_dir[] = $cdrec; 
} 
function filezip(){ 
$data = implode('', $this -> datasec); 
$ctrldir = implode('', $this -> ctrl_dir); 
return 
$data . 
$ctrldir . 
$this -> eof_ctrl_dir . 
pack('v', sizeof($this -> ctrl_dir)) . // total # of entries "on this disk" 
pack('v', sizeof($this -> ctrl_dir)) . // total # of entries overall 
pack('V', strlen($ctrldir)) . // size of central dir 
pack('V', strlen($data)) . // offset to start of central dir 
"/x00/x00"; // .zip file comment length 
} 
} 
?>

PHP 相关文章推荐
Php部分常见问题总结
Oct 09 PHP
PHP如何得到当前页和上一页的地址?
Nov 27 PHP
与文件上传有关的php配置参数总结
Jun 14 PHP
CodeIgniter框架中_remap()使用方法2例
Mar 10 PHP
ThinkPHP Mobile使用方法简明教程
Jun 18 PHP
php中获取主机名、协议及IP地址的方法
Nov 18 PHP
PHP AjaxForm提交图片上传并显示图片源码
Nov 29 PHP
yii2局部关闭(开启)csrf的验证的实例代码
Jul 10 PHP
CMSPRESS 10行代码搞定 PHP无限级分类2
Mar 30 PHP
PHP封装的分页类与简单用法示例
Feb 25 PHP
详解将数据从Laravel传送到vue的四种方式
Oct 16 PHP
php实现通过stomp协议连接ActiveMQ操作示例
Feb 23 PHP
基于php iconv函数的使用详解
Jun 09 #PHP
PHP页面间参数传递的四种方法详解
Jun 09 #PHP
利用PHP+JS实现搜索自动提示(实例)
Jun 09 #PHP
深入php处理整数函数的详解
Jun 09 #PHP
解决ajax+php中文乱码的方法详解
Jun 09 #PHP
PHP写的加密函数,支持私人密钥(详细介绍)
Jun 09 #PHP
PHP版 汉字转码的实现详解
Jun 09 #PHP
You might like
PHP的魔术常量__METHOD__简介
2014/07/08 PHP
php上传文件并存储到mysql数据库的方法
2015/03/16 PHP
PDO::errorCode讲解
2019/01/28 PHP
PHP下用Swoole实现Actor并发模型的方法
2019/06/12 PHP
php数组指针函数功能及用法示例
2020/02/11 PHP
jquery索引在使用中的一些困惑
2013/10/24 Javascript
JS实现切换标签页效果实例代码
2013/11/01 Javascript
跟我学习javascript的var预解析与函数声明提升
2015/11/16 Javascript
Immutable 在 JavaScript 中的应用
2016/05/02 Javascript
基于BootStrap Metronic开发框架经验小结【六】对话框及提示框的处理和优化
2016/05/12 Javascript
Angular的Bootstrap(引导)和Compiler(编译)机制
2016/06/20 Javascript
js中获取 table节点各tr及td的内容简单实例
2016/10/14 Javascript
AngularJS页面传参的5种方式
2017/04/01 Javascript
微信小程序 新建登录页并实现tabBar隐藏
2017/06/13 Javascript
实现两个文本框同时输入的实例
2017/09/25 Javascript
解决vue中修改export default中脚本报一大堆错的问题
2018/08/27 Javascript
vue滚动固定顶部及修改样式的实例代码
2019/05/30 Javascript
python写入中英文字符串到文件的方法
2015/05/06 Python
使用python实现rsa算法代码
2016/02/17 Python
Go语言基于Socket编写服务器端与客户端通信的实例
2016/02/19 Python
Python简单的制作图片验证码实例
2017/05/31 Python
Python八大常见排序算法定义、实现及时间消耗效率分析
2018/04/27 Python
解决win7操作系统Python3.7.1安装后启动提示缺少.dll文件问题
2019/07/15 Python
Django如何将URL映射到视图
2019/07/29 Python
Python3使用腾讯云文字识别(腾讯OCR)提取图片中的文字内容实例详解
2020/02/18 Python
python 子类调用父类的构造函数实例
2020/03/12 Python
详解用Pytest+Allure生成漂亮的HTML图形化测试报告
2020/03/31 Python
python 实现关联规则算法Apriori的示例
2020/09/30 Python
python爬取股票最新数据并用excel绘制树状图的示例
2021/03/01 Python
利用CSS3实现平移动画效果示例代码
2016/10/12 HTML / CSS
html5 跨文档消息传输示例探讨
2013/04/01 HTML / CSS
简单html5代码获取地理位置
2014/03/31 HTML / CSS
一组SQL面试题
2016/02/15 面试题
2014年挂职干部工作总结
2014/12/06 职场文书
js前端图片加载异常兜底方案
2022/06/21 Javascript
使用Postman测试需要授权的接口问题
2022/06/21 Java/Android