搜索

QQ登录

只需一步,快速开始

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1522|回复: 1

将文件夹压缩成zip文件的php代码、实现批量下载

[复制链接]

4775

主题

4899

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
15234

社区QQ达人

发表于 2014-10-1 23:22:59 | 显示全部楼层 |阅读模式
在php中生成zip其实很简单,只要下面2步就能完成。
1.请先下载我准备好的zip.php工具类,下载后解压,将里面的文件放入对应的目录中,我是放在虚拟目录下的include文件夹中。
2.在你的php文件中加入下面代码即可
  1. require_once "./include/zip.php";
  2. $zip = new PHPZip();
  3. //$zip -> createZip("要压缩的文件夹目录地址", "压缩后的文件名.zip");   //只生成不自动下载
  4. $zip -> downloadZip("要压缩的文件夹目录地址", "压缩后的文件名.zip");  //自动下载
复制代码

实例:可以参考下面的伪代码来看一个具体的使用场景:
代码
  1. require_once "./include/zip.php";
  2. if (!$download) {
  3. exit();
  4. }
  5. set_time_limit(60);
  6. $tmpManager = new TmpManager(); //假设我们有一个类来完成后面的操作
  7. $tempfolder = array();
  8. $tempfile = array();
  9. //假设我们是通过在页面上选择checkbox来下载已选的文件夹或文件,并一同打包
  10. for($i = 0;$i < $checkboxnum;$i++) {
  11. $value = ${"select".$i};
  12. if ($value != '') {
  13. $this_type = substr($value, 0, 1);
  14. $this_id = substr($value, 1);
  15. //将文件夹和文件的情况分开处理
  16. if ($this_type == 'd') {
  17. $tempfolder[] = $this_id;
  18. }
  19. elseif ($this_type == 'f') {
  20. $tempfile[] = $this_id;
  21. }
  22. }
  23. }
  24. @mkdir($tempdir);
  25. $curtempdir = "$tempdir/".$userid; //不同用户在不同的临时文件夹下操作
  26. if (file_exists($curtempdir)) {
  27. $tmpManager->DeleteDir($curtempdir); //删除旧的文件夹
  28. }
  29. if (sizeof($tempfolder) > 0 || sizeof($tempfile) > 0) {
  30. mkdir($curtempdir, 0777); //如果有要打包的文件货文件夹,重新创建文件夹
  31. }
  32. if (sizeof($tempfile) > 0) {
  33. $tmpManager->CopyFile($tempfile,$curtempdir); //将要下载的文件copy到创建的文件夹
  34. }
  35. if (sizeof($tempfolder) > 0) {
  36. $tmpManager->CopyFolder($tempfolder,$curtempdir); //将要下载的文件夹copy到创建的文件夹
  37. }
  38. $zip = new PHPZip();
  39. $zip -> downloadZip($curtempdir, "file_".date('Ymd').".zip"); //打包并下载
复制代码
zip.php
  1. <?php
  2. /*
  3.     File name: /include/zip.php
  4.     Author:    Horace 2009/04/15
  5. */
  6. class PHPZip{
  7.     var $dirInfo = array("0","0");
  8.     var $rootDir = '';
  9.     var $datasec = array();
  10.     var $ctrl_dir = array();
  11.     var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
  12.     var $old_offset = 0;

  13.     function downloadZip(){
  14.         createZip($dir, $zipfilename, true);
  15.     }
  16.     function createZip($dir, $zipfilename, $autoDownload = false){
  17.         if (@function_exists('gzcompress')){
  18.             @set_time_limit("0");
  19.             if (is_array($dir)){
  20.                 $fd = fopen ($dir, "r");
  21.                 $fileValue = fread ($fd, filesize ($filename));
  22.                 fclose ($fd);
  23.                 if (is_array($dir)) $filename = basename($dir);
  24.                 $this -> addFile($fileValue, "$filename");
  25.             }else{
  26.                 $this->dirTree($dir,$dir);
  27.             }

  28.             $zipfilenametemp = time().$zipfilename;
  29.             $out = $this -> filezip();
  30.             $fp = fopen($zipfilenametemp, "w");
  31.             fwrite($fp, $out, strlen($out));
  32.             fclose($fp);
  33.             $filesize = filesize($zipfilenametemp);

  34.             if ($filesize < 104857600) {
  35.                 if($autoDownload){
  36.                     header("Content-type: application/octet-stream");
  37.                     header("Content-disposition: attachment; filename=".$zipfilename);
  38.                 }
  39.                 echo $this -> filezip();
  40.             }else{
  41.                 echo "create zip error!";
  42.             }
  43.             unlink($zipfilenametemp);
  44.         }
  45.      }
  46.     //get dir tree..
  47.     function dirTree($directory,$rootDir){
  48.         global $_SERVER,$dirInfo,$rootDir;

  49.         $fileDir=$rootDir;
  50.         $myDir=dir($directory);
  51.         while($file=$myDir->read()){
  52.             if(is_dir("$directory/$file") and $file!="." and $file!=".."){
  53.                 $dirInfo[0]++;
  54.                 $rootDir ="$fileDir$file/";

  55.                 $this -> addFile('', "$rootDir");

  56.                 //go on n's folders
  57.                 $this->dirTree("$directory/$file",$rootDir);
  58.             }else{
  59.                 if($file!="." and $file!=".."){
  60.                     $dirInfo[1]++;
  61.                     //$fd = fopen ("$directory/$file", "r");
  62.                     $fileValue = file_get_contents("$directory/$file");
  63.                     //fclose ($fd);
  64.                     $this -> addFile($fileValue, "$fileDir$file");
  65.                 }
  66.             }
  67.         }
  68.         $myDir->close();
  69.     }
  70. function unix2DosTime($unixtime = 0) {
  71. $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);

  72. if ($timearray['year'] < 1980) {
  73.      $timearray['year'] = 1980;
  74.      $timearray['mon'] = 1;
  75.      $timearray['mday'] = 1;
  76.      $timearray['hours'] = 0;
  77.      $timearray['minutes'] = 0;
  78.      $timearray['seconds'] = 0;
  79. } // end if

  80. return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) |
  81. ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
  82. }
  83. function addFile($data, $name, $time = 0){
  84. $name = str_replace('\\', '/', $name);

  85. $dtime = dechex($this->unix2DosTime($time));
  86. $hexdtime = '\x' . $dtime[6] . $dtime[7]
  87. . '\x' . $dtime[4] . $dtime[5]
  88. . '\x' . $dtime[2] . $dtime[3]
  89. . '\x' . $dtime[0] . $dtime[1];
  90. eval('$hexdtime = "' . $hexdtime . '";');

  91. $fr = "\x50\x4b\x03\x04";
  92. $fr .= "\x14\x00"; // ver needed to extract
  93. $fr .= "\x00\x00"; // gen purpose bit flag
  94. $fr .= "\x08\x00"; // compression method
  95. $fr .= $hexdtime; // last mod time and date

  96. // "local file header" segment
  97. $unc_len = strlen($data);
  98. $crc = crc32($data);
  99. $zdata = gzcompress($data);
  100. $c_len = strlen($zdata);
  101. $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
  102. $fr .= pack('V', $crc); // crc32
  103. $fr .= pack('V', $c_len); // compressed filesize
  104. $fr .= pack('V', $unc_len); // uncompressed filesize
  105. $fr .= pack('v', strlen($name)); // length of filename
  106. $fr .= pack('v', 0); // extra field length
  107. $fr .= $name;

  108. // "file data" segment
  109. $fr .= $zdata;

  110. // "data descriptor" segment (optional but necessary if archive is not
  111. // served as file)
  112. $fr .= pack('V', $crc); // crc32
  113. $fr .= pack('V', $c_len); // compressed filesize
  114. $fr .= pack('V', $unc_len); // uncompressed filesize

  115. // add this entry to array
  116. $this -> datasec[] = $fr;
  117. $new_offset = strlen(implode('', $this->datasec));

  118. // now add to central directory record
  119. $cdrec = "\x50\x4b\x01\x02";
  120. $cdrec .= "\x00\x00"; // version made by
  121. $cdrec .= "\x14\x00"; // version needed to extract
  122. $cdrec .= "\x00\x00"; // gen purpose bit flag
  123. $cdrec .= "\x08\x00"; // compression method
  124. $cdrec .= $hexdtime; // last mod time & date
  125. $cdrec .= pack('V', $crc); // crc32
  126. $cdrec .= pack('V', $c_len); // compressed filesize
  127. $cdrec .= pack('V', $unc_len); // uncompressed filesize
  128. $cdrec .= pack('v', strlen($name) ); // length of filename
  129. $cdrec .= pack('v', 0 ); // extra field length
  130. $cdrec .= pack('v', 0 ); // file comment length
  131. $cdrec .= pack('v', 0 ); // disk number start
  132. $cdrec .= pack('v', 0 ); // internal file attributes
  133. $cdrec .= pack('V', 32 ); // external file attributes - 'archive' bit set

  134. $cdrec .= pack('V', $this -> old_offset ); // relative offset of local header
  135. $this -> old_offset = $new_offset;

  136. $cdrec .= $name;

  137. // optional extra field, file comment goes here
  138. // save to central directory
  139. $this -> ctrl_dir[] = $cdrec;
  140. }
  141. function filezip(){
  142. $data = implode('', $this -> datasec);
  143. $ctrldir = implode('', $this -> ctrl_dir);

  144. return
  145. $data .
  146. $ctrldir .
  147. $this -> eof_ctrl_dir .
  148. pack('v', sizeof($this -> ctrl_dir)) . // total # of entries "on this disk"
  149. pack('v', sizeof($this -> ctrl_dir)) . // total # of entries overall
  150. pack('V', strlen($ctrldir)) . // size of central dir
  151. pack('V', strlen($data)) . // offset to start of central dir
  152. "\x00\x00"; // .zip file comment length
  153. }
  154. }
  155. ?>
复制代码



分享到: 更多
友荐云推荐
射中网 www.shezhong.net 娄底街 www.loudijie.com 育儿之家 www.yuerso.com
回复

使用道具 举报

4775

主题

4899

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
15234

社区QQ达人

 楼主| 发表于 2014-10-1 23:23:14 | 显示全部楼层
射中网 www.shezhong.net 娄底街 www.loudijie.com 育儿之家 www.yuerso.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

GMT+8, 2020-8-9 13:03

© 2001-2011 Powered by Discuz! X3.1. Theme By Yeei!

快速回复 返回顶部 返回列表