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中动态显示签名和ip原理
Mar 28 PHP
mysql 字段类型说明
Apr 27 PHP
PHP开发中常用的三个表单验证函数使用小结
Mar 03 PHP
php 过滤英文标点符号及过滤中文标点符号代码
Jun 12 PHP
PHP不用递归遍历目录下所有文件的代码
Jul 04 PHP
laravel安装和配置教程
Oct 29 PHP
主流PHP框架的优缺点对比分析
Dec 25 PHP
php中文验证码实现方法
Jun 18 PHP
PHP MVC框架路由学习笔记
Mar 02 PHP
PHP yii实现model添加默认值的方法(两种方法)
Nov 10 PHP
Laravel 微信小程序后端搭建步骤详解
Nov 26 PHP
PHP超级全局变量【$GLOBALS,$_SERVER,$_REQUEST等】用法实例分析
Dec 11 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
咖啡磨器 如何选购一台适合家用的意式磨豆机
2021/03/05 新手入门
php数据库连接时容易出错的特殊符号问题
2010/09/01 PHP
php笔记之:php函数range() round()和list()的使用说明
2013/04/26 PHP
ThinkPHP中URL路径访问与模块控制器之间的关系
2014/08/23 PHP
Symfony2安装第三方Bundles实例详解
2016/02/04 PHP
Thinkphp实现站点静态化的方法详解
2017/03/21 PHP
js各种验证文本框输入格式(正则表达式)
2010/10/22 Javascript
js去除重复字符串两种实现方法
2013/01/09 Javascript
Jquery节点遍历next与nextAll方法使用示例
2014/07/22 Javascript
jQuery的css()方法用法实例
2014/12/24 Javascript
XML文件转化成NSData对象的方法
2015/08/12 Javascript
Bootstrap Paginator分页插件与ajax相结合实现动态无刷新分页效果
2016/05/27 Javascript
JS组件系列之MVVM组件构建自己的Vue组件
2017/04/28 Javascript
利用10行js代码实现上下滚动公告效果
2017/12/08 Javascript
教你如何编写Vue.js的单元测试的方法
2018/10/17 Javascript
JS实现的图片选择顺序切换和循环切换功能示例【测试可用】
2018/12/28 Javascript
nodejs搭建本地服务器并访问文件操作示例
2019/05/11 NodeJs
你知道JavaScript Symbol类型怎么用吗
2020/01/08 Javascript
JS实现滑动拼图验证功能完整示例
2020/03/29 Javascript
微信小程序多列表渲染数据开关互不影响的实现
2020/06/05 Javascript
[01:38]【DOTA2亚洲邀请赛】Sumail——梦开始的地方
2017/03/03 DOTA
Python实现全角半角字符互转的方法
2016/11/28 Python
Python爬虫设置代理IP的方法(爬虫技巧)
2018/03/04 Python
Python wxPython库使用wx.ListBox创建列表框示例
2018/09/03 Python
python+Django实现防止SQL注入的办法
2019/10/31 Python
布局和排版教程 纯css3实现图片三角形排列
2014/10/17 HTML / CSS
CSS3制作炫酷带方向感应的鼠标滑过图片3D动画
2016/03/16 HTML / CSS
简述进程的启动、终止的方式以及如何进行进程的查看
2014/02/20 面试题
服务生自我鉴定
2014/01/22 职场文书
化妆师职业生涯规划书
2014/02/16 职场文书
销售顾问工作计划书
2014/08/15 职场文书
医生爱岗敬业演讲稿
2014/08/26 职场文书
母亲节主题班会
2015/08/14 职场文书
幼儿园小班教育随笔
2015/08/14 职场文书
小学教师师德培训心得体会
2016/01/09 职场文书
只需要12页,掌握撰写一流商业计划书的技巧
2019/05/07 职场文书