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 和 XML: 使用expat函数(一)
Oct 09 PHP
PHP图片处理之使用imagecopyresampled函数裁剪图片例子
Nov 19 PHP
详解PHP实现定时任务的五种方法
Jul 25 PHP
超强多功能php绿色集成环境详解
Jan 25 PHP
PHP编程计算两个时间段是否有交集的实现方法(不算边界重叠)
May 30 PHP
PHP mysqli事务操作常用方法分析
Jul 22 PHP
PHP异常处理定义与使用方法分析
Jul 25 PHP
php实现与python进行socket通信的方法示例
Aug 30 PHP
Yii2 queue的队列使用详解
Jul 19 PHP
Yii2.0框架behaviors方法使用实例分析
Sep 30 PHP
解决Laravel 不能创建 migration 的问题
Oct 09 PHP
Laravel使用swoole实现websocket主动消息推送的方法介绍
Oct 20 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中session变量的销毁
2014/02/27 PHP
thinkPHP显示不出验证码的原因与解决方法分析
2017/05/20 PHP
php 猴子摘桃的算法
2017/06/20 PHP
jQuery中验证表单提交方式及序列化表单内容的实现
2014/01/06 Javascript
使用JS或jQuery模拟鼠标点击a标签事件代码
2014/03/10 Javascript
浅谈jquery回调函数callback的使用
2015/01/30 Javascript
NodeJS的Promise的用法解析
2016/05/05 NodeJs
过期软件破解办法实例详解
2017/01/04 Javascript
从零学习node.js之express入门(六)
2017/02/25 Javascript
详解Vue2 无限级分类(添加,删除,修改)
2017/03/07 Javascript
JS实现简单拖拽效果
2017/06/21 Javascript
webpack4.0 入门实践教程
2018/10/08 Javascript
利用Electron简单撸一个Markdown编辑器的方法
2019/06/10 Javascript
Vue3项目打包后部署到服务器 请求不到后台接口解决方法
2020/02/06 Javascript
JavaScript 实现继承的几种方式
2021/02/19 Javascript
简单分析Python中用fork()函数生成的子进程
2015/05/04 Python
python 3利用Dlib 19.7实现摄像头人脸检测特征点标定
2018/02/26 Python
为什么入门大数据选择Python而不是Java?
2018/03/07 Python
Python之pandas读写文件乱码的解决方法
2018/04/20 Python
Python3.5常见内置方法参数用法实例详解
2019/04/29 Python
解决.ui文件生成的.py文件运行不出现界面的方法
2019/06/19 Python
浅谈PyTorch的可重复性问题(如何使实验结果可复现)
2020/02/20 Python
浅谈Python中的模块
2020/06/10 Python
Python错误的处理方法
2020/06/23 Python
详解python tcp编程
2020/08/24 Python
Python自动化之UnitTest框架实战记录
2020/09/08 Python
电子商务毕业生求职信
2013/11/10 职场文书
党员干部承诺书
2014/03/25 职场文书
2015年新学期寄语
2015/02/26 职场文书
2015年感恩节演讲稿(优选篇)
2015/03/20 职场文书
漂亮妈妈观后感
2015/06/08 职场文书
运动会运动员赞词
2015/07/22 职场文书
严以用权学习心得体会
2016/01/12 职场文书
导游词之新疆-喀纳斯
2019/10/10 职场文书
Typescript类型系统FLOW静态检查基本规范
2022/05/25 Javascript
使用Postman测试需要授权的接口问题
2022/06/21 Java/Android