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 相关文章推荐
不用GD库生成当前时间的PNG格式图象的程序
Oct 09 PHP
初级的用php写的采集程序
Mar 16 PHP
MySQL数据源表结构图示
Jun 05 PHP
php array_walk() 数组函数
Jul 12 PHP
浅析PHP原理之变量(Variables inside PHP)
Aug 09 PHP
php5.4以下版本json不支持不转义内容中文的解决方法
Jan 13 PHP
php对象和数组相互转换的方法
May 12 PHP
php metaphone()函数的定义和用法
May 15 PHP
PHP简单判断手机设备的方法
Aug 23 PHP
php利用递归实现删除文件目录的方法
Sep 23 PHP
利用PHP_XLSXWriter代替PHPExcel的方法示例
Jul 16 PHP
php下的原生ajax请求用法实例分析
Feb 28 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压缩html网页代码(清除空格,换行符,制表符,注释标记)
2012/04/02 PHP
PHP通过session id 实现session共享和登录验证的代码
2012/06/03 PHP
php中require和require_once的区别说明
2014/02/27 PHP
使用配置类定义Codeigniter全局变量
2014/06/12 PHP
thinkPHP多域名情况下使用memcache方式共享session数据的实现方法
2016/07/21 PHP
laravel7学习之无限级分类的最新实现方法
2020/09/30 PHP
DOMAssitant最新版 DOMAssistant 2.5发布
2007/12/25 Javascript
基于jQuery实现的水平和垂直居中的div窗口
2011/08/08 Javascript
nodejs开发微博实例
2015/03/25 NodeJs
flash+jQuery实现可关闭及重复播放的压顶广告
2015/04/15 Javascript
js实现基于正则表达式的轻量提示插件
2015/08/29 Javascript
js一维数组、多维数组和对象的混合使用方法
2016/04/03 Javascript
jQuery操作cookie
2016/08/08 Javascript
JS+HTML5实现的前端购物车功能插件实例【附demo源码下载】
2016/10/17 Javascript
扩展jquery easyui tree的搜索树节点方法(推荐)
2016/10/28 Javascript
webstrom Debug 调试vue项目的方法步骤
2018/07/17 Javascript
vue的token刷新处理的方法
2018/07/17 Javascript
JavaScript 复制对象与Object.assign方法无法实现深复制
2018/11/02 Javascript
node app 打包工具pkg的具体使用
2019/01/17 Javascript
一个Java程序猿眼中的前后端分离以及Vue.js入门(推荐)
2019/04/19 Javascript
详解微信小程序支付流程与梳理
2019/07/16 Javascript
Javascript地址引用代码实例解析
2020/02/25 Javascript
Vue仿百度搜索功能
2020/12/28 Vue.js
Python下的Mysql模块MySQLdb安装详解
2014/04/09 Python
Python编写电话薄实现增删改查功能
2016/05/07 Python
python定时按日期备份MySQL数据并压缩
2019/04/19 Python
在服务器上安装python3.8.2环境的教程详解
2020/04/26 Python
使用ITK-SNAP进行抠图操作并保存mask的实例
2020/07/01 Python
LORAC官网:美国彩妆品牌
2019/08/27 全球购物
GWebs公司笔试题
2012/05/04 面试题
初级会计求职信范文
2014/02/15 职场文书
大学生创业项目方案
2014/03/08 职场文书
股东协议书
2014/04/14 职场文书
工作求职自荐信
2014/06/13 职场文书
2016党员学习心得体会范文
2016/01/23 职场文书
详解Redis瘦身指南
2021/05/26 Redis