PHP在线压缩ZIP文件程序

汉王 PHP 2016年01月12日 收藏
  1. <?php
  2. //在URL后参加 ?pwd=密码 查看生成密码
  3. $password = 'd328ab8f8bcf16888c9a12e480a414d4';
  4. ?>
  5. <form name="myform" id="myform" method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
  6. <h1 style="color:#2583ad;">在线压缩ZIP文件程序</h1><br>
  7. <div>
  8.       <p>使用方法:选定要压缩的文件或目录(包含子目录),即可开始压缩。压缩的结果保留原来的目录结构。<br />
  9.       <?php if(isset($_REQUEST['pwd']) && md5($_REQUEST['pwd']) == $password)
  10.  echo '当前目录:<span>'. dirname(__FILE__) . '</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="'.
  11.  $_SERVER['PHP_SELF']. '">退出</a>';
  12.    else
  13. if(isset($_GET['pwd']) )
  14. echo '密码值:<span>'. md5($_GET['pwd']) . '</span>';
  15. else
  16. echo 'Tips:在URL后参加<span>?pwd=密码</span> 查看生成密码.';
  17.      ?>
  18.  </p>
  19. </div>
  20. <?
  21. if(!isset($_REQUEST["myaction"])):
  22. ?>
  23. <table width="100%" border="0" cellspacing="0" cellpadding="0">
  24. <tr>
  25.       <td width="11%">验证密码: </td>
  26.       <td width="89%"><input name="pwd" type="password" id="password" size="30" onkeydown="if(event.ctrlKey&&event.keyCode==13){document.getElementById('login').click();return false};"></td>
  27.     </tr>
  28.     <tr>
  29.       <td><input name="myaction" type="hidden" id="myaction" value="dolist"></td>
  30.       <td><input type="submit" name="Submit" id="login" value=" 进 入 "></td>
  31.     </tr>
  32.   </table>
  33.   <script type="text/javascript">
  34.   document.getElementById('password').focus();
  35.   </script>
  36. <?
  37. elseif($_REQUEST["myaction"]=="dolist"):
  38. if(!isset($_REQUEST['pwd']) || empty($_REQUEST['pwd']) )
  39. die('请输入密码! <a href="'. $_SERVER['PHP_SELF']. '">Again</a>');
  40. if(md5($_REQUEST['pwd']) != $password) 
  41.    die('输入的密码不正确!<a href="'. $_SERVER['PHP_SELF']. '">Again</a>');
  42. echo '选择要排除的目录(相对路径,以英文半角逗号分隔):<br />';
  43. echo '<input type="text" id="toexlude" name="toexlude" size="100" /><br />';
  44. echo "选择要压缩的文件或目录:<br/>";
  45.    $fdir = opendir('./');
  46. while($file=readdir($fdir)){
  47. if($file=='.'|| $file=='..' ) continue;
  48. echo "<input name='dfile[]' type='checkbox' value='$file' ".($file==basename(__FILE__)?"":"checked")."> ";
  49. if(is_file($file)){
  50. echo "<span>文件: $file</span><br>";
  51. }else{
  52. echo "<span>目录: $file</span><br>";
  53. }
  54. }
  55. ?>
  56. <br>

压缩文件保存到目录: 

  1. <input name="todir" type="text" id="todir" value="_zipfiles<?php echo substr(md5(time()),0,8);?>_" size="20">

(留空为本目录,必须有写入权限)<br>

压缩文件名称:

  1. <input name="zipname" type="text" id="zipname" value="backup_<?php echo substr(md5(__FILE__),0,8);?>.zip" size="15">(.zip)


  1. <input name="pwd" type="hidden" id="password" value="<?php echo $_POST['pwd'];?>">
  2. <input name="myaction" type="hidden" id="myaction" value="dozip">
  3. <input type='button' value='反选' onclick='selrev();'>
  4. <input type="submit" name="Submit" value=" 开始压缩 ">
  5. <script language='javascript'>
  6. function selrev() {
  7. with(document.getElementById('myform')){
  8. for(i=0;i<elements.length;i++) {
  9. thiselm = elements[i];
  10. if(thiselm.name.match(/dfile\[]/)) thiselm.checked = !thiselm.checked;
  11. }
  12. }
  13. }
  14. </script>
  15. <?
  16. elseif($_REQUEST["myaction"]=="dozip"):
  17. //  set_time_limit(0);
  18.   class PHPzip{
  19. var $file_count = 0 ;
  20. var $datastr_len   = 0;
  21. var $dirstr_len = 0;
  22. var $filedata = ''; //该变量只被类外部程序访问
  23. var $gzfilename;
  24. var $fp;
  25. var $dirstr='';
  26. /*
  27. 返回文件的修改时间格式.
  28. 只为本类内部函数调用.
  29. */
  30.     function unix2DosTime($unixtime = 0) {
  31.         $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);
  32.         if ($timearray['year'] < 1980) {
  33.          $timearray['year']    = 1980;
  34.          $timearray['mon']     = 1;
  35.          $timearray['mday']    = 1;
  36.          $timearray['hours']   = 0;
  37.          $timearray['minutes'] = 0;
  38.          $timearray['seconds'] = 0;
  39.         }
  40.         return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) |
  41.                ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
  42.     }
  43. /*
  44. 初始化文件,建立文件目录,
  45. 并返回文件的写入权限.
  46. */
  47. function startfile($path = 'myzip.zip'){
  48. $this->gzfilename=$path;
  49. $mypathdir=array();
  50. do{
  51. $mypathdir[] = $path = dirname($path);
  52. }while($path != '.');
  53. @end($mypathdir);
  54. do{
  55. $path = @current($mypathdir);
  56. @mkdir($path);
  57. }while(@prev($mypathdir));
  58. if($this->fp=@fopen($this->gzfilename,"w")){
  59. return true;
  60. }
  61. return false;
  62. }
  63. /*
  64. 添加一个文件到 zip 压缩包中.
  65. */
  66.     function addfile($data, $name){
  67.         $name     = str_replace('\\', '/', $name);
  68. if(strrchr($name,'/')=='/') return $this->adddir($name);
  69.         $dtime    = dechex($this->unix2DosTime());
  70.         $hexdtime = '\x' . $dtime[6] . $dtime[7]
  71.                   . '\x' . $dtime[4] . $dtime[5]
  72.                   . '\x' . $dtime[2] . $dtime[3]
  73.                   . '\x' . $dtime[0] . $dtime[1];
  74.         eval('$hexdtime = "' . $hexdtime . '";');
  75.         $unc_len = strlen($data);
  76.         $crc     = crc32($data);
  77.         $zdata   = gzcompress($data);
  78.         $c_len   = strlen($zdata);
  79.         $zdata   = substr(substr($zdata, 0, strlen($zdata) - 4), 2);
  80. //新添文件内容格式化:
  81.         $datastr  = "\x50\x4b\x03\x04";
  82.         $datastr .= "\x14\x00";            // ver needed to extract
  83.         $datastr .= "\x00\x00";            // gen purpose bit flag
  84.         $datastr .= "\x08\x00";            // compression method
  85.         $datastr .= $hexdtime;             // last mod time and date
  86.         $datastr .= pack('V', $crc);             // crc32
  87.         $datastr .= pack('V', $c_len);           // compressed filesize
  88.         $datastr .= pack('V', $unc_len);         // uncompressed filesize
  89.         $datastr .= pack('v', strlen($name));    // length of filename
  90.         $datastr .= pack('v', 0);                // extra field length
  91.         $datastr .= $name;
  92.         $datastr .= $zdata;
  93.         $datastr .= pack('V', $crc);                 // crc32
  94.         $datastr .= pack('V', $c_len);               // compressed filesize
  95.         $datastr .= pack('V', $unc_len);             // uncompressed filesize
  96. fwrite($this->fp,$datastr); //写入新的文件内容
  97. $my_datastr_len = strlen($datastr);
  98. unset($datastr);
  99. //新添文件目录信息
  100.         $dirstr  = "\x50\x4b\x01\x02";
  101.         $dirstr .= "\x00\x00";                 // version made by
  102.         $dirstr .= "\x14\x00";                 // version needed to extract
  103.         $dirstr .= "\x00\x00";                 // gen purpose bit flag
  104.         $dirstr .= "\x08\x00";                 // compression method
  105.         $dirstr .= $hexdtime;                  // last mod time & date
  106.         $dirstr .= pack('V', $crc);            // crc32
  107.         $dirstr .= pack('V', $c_len);          // compressed filesize
  108.         $dirstr .= pack('V', $unc_len);        // uncompressed filesize
  109.         $dirstr .= pack('v', strlen($name) );  // length of filename
  110.         $dirstr .= pack('v', 0 );              // extra field length
  111.         $dirstr .= pack('v', 0 );              // file comment length
  112.         $dirstr .= pack('v', 0 );              // disk number start
  113.         $dirstr .= pack('v', 0 );              // internal file attributes
  114.         $dirstr .= pack('V', 32 );             // external file attributes - 'archive' bit set
  115.         $dirstr .= pack('V',$this->datastr_len ); // relative offset of local header
  116.         $dirstr .= $name;
  117. $this->dirstr .= $dirstr; //目录信息
  118. $this -> file_count ++;
  119. $this -> dirstr_len += strlen($dirstr);
  120. $this -> datastr_len += $my_datastr_len;
  121.     }
  122. function adddir($name){ 
  123. $name = str_replace("\\", "/", $name); 
  124. $datastr = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"; 
  125. $datastr .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) ); 
  126. $datastr .= pack("v", 0 ).$name.pack("V", 0).pack("V", 0).pack("V", 0); 
  127. fwrite($this->fp,$datastr); //写入新的文件内容
  128. $my_datastr_len = strlen($datastr);
  129. unset($datastr);
  130. $dirstr = "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"; 
  131. $dirstr .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) ); 
  132. $dirstr .= pack("v", 0 ).pack("v", 0 ).pack("v", 0 ).pack("v", 0 ); 
  133. $dirstr .= pack("V", 16 ).pack("V",$this->datastr_len).$name; 
  134. $this->dirstr .= $dirstr; //目录信息
  135. $this -> file_count ++;
  136. $this -> dirstr_len += strlen($dirstr);
  137. $this -> datastr_len += $my_datastr_len;
  138. }
  139. function createfile(){
  140. //压缩包结束信息,包括文件总数,目录信息读取指针位置等信息
  141. $endstr = "\x50\x4b\x05\x06\x00\x00\x00\x00" .
  142. pack('v', $this -> file_count) .
  143. pack('v', $this -> file_count) .
  144. pack('V', $this -> dirstr_len) .
  145. pack('V', $this -> datastr_len) .
  146. "\x00\x00";
  147. fwrite($this->fp,$this->dirstr.$endstr);
  148. fclose($this->fp);
  149. }
  150.   }
  151. if(!trim($_REQUEST['zipname'])) 
  152. $_REQUEST['zipname'] = 'backup_'.substr(md5(__FILE__),0,8). '.zip'; 
  153. else 
  154. $_REQUEST['zipname'] = trim($_REQUEST['zipname']);
  155. if(!strrchr(strtolower($_REQUEST['zipname']),'.')=='.zip') 
  156. $_REQUEST['zipname'] .= ".zip";
  157. $_REQUEST['todir'] = str_replace('\\','/',trim($_REQUEST['todir']));
  158. if(!strrchr(strtolower($_REQUEST['todir']),'/')=='/') 
  159. $_REQUEST['todir'] .= "/";
  160. if($_REQUEST['todir']=="/") 
  161. $_REQUEST['todir'] = "./";
  162. function listfiles($dir="."){
  163. global $faisunZIP;
  164. $sub_file_num = 0;
  165. if(is_file($dir)){
  166.  if(realpath($faisunZIP->gzfilename)!=realpath($dir)){
  167. $faisunZIP -> addfile(implode('',file($dir)),$dir);
  168. return 1;
  169.  }
  170. return 0;
  171. }
  172. $handle=opendir($dir);
  173. //添加排除
  174. $to_exlude = !empty($_POST['toexlude']) ? $_POST['toexlude'] :'';
  175. $exlude = empty($to_exlude) ? array() : explode(',',$to_exlude);
  176. while ($file = readdir($handle)) {
  177.   if($file=="."||$file==".." || $file == 'wp-content' )continue;
  178.   if(is_dir("$dir/$file") && !in_array("$dir/$file",$exlude) )
  179.   {
  180. $sub_file_num += listfiles("$dir/$file");
  181.   }
  182.   else {
  183.       if(realpath($faisunZIP ->gzfilename)!=realpath("$dir/$file")){
  184.     $faisunZIP -> addfile(implode('',file("$dir/$file")),"$dir/$file");
  185. $sub_file_num ++;
  186. }
  187.   }
  188. }
  189. closedir($handle);
  190. if(!$sub_file_num) $faisunZIP -> addfile("","$dir/");
  191. return $sub_file_num;
  192. }
  193. function num_bitunit($num){
  194.  $bitunit=array(' B',' KB',' MB',' GB');
  195.  for($key=0;$key<count($bitunit);$key++){
  196. if($num>=pow(2,10*$key)-1){ //1023B 会显示为 1KB
  197.  $num_bitunit_str=(ceil($num/pow(2,10*$key)*100)/100)." $bitunit[$key]";
  198. }
  199.  }
  200.  return $num_bitunit_str;
  201. }
  202. if(is_array($_REQUEST['dfile'])){
  203. $faisunZIP = new PHPzip;
  204. if($faisunZIP -> startfile($_REQUEST['todir'].$_REQUEST['zipname'])){
  205. echo "正在添加压缩文件...<br><br>";
  206. $filenum = 0;
  207. foreach($_REQUEST['dfile'] as $file){
  208. if(is_file($file)){
  209. echo "<span>文件: $file </span><br>";
  210. }else{
  211. echo "<span>目录: $file </span><br>";
  212. }
  213. $filenum += listfiles($file);
  214. }
  215. $faisunZIP -> createfile();
  216. echo "<br>压缩完成,共添加 $filenum 个文件.<br /><a href='" .$_REQUEST['todir'].$_REQUEST['zipname']. "'>". $_REQUEST['todir'].$_REQUEST['zipname']." (".num_bitunit(filesize("$_REQUEST[todir]$_REQUEST[zipname]")).")</a>";
  217. }else{
  218. echo $_REQUEST['todir'].$_REQUEST['zipname'].'不能写入,请检查路径或权限是否正确.<br>';
  219. }
  220. }else{
  221. echo "没有选择的文件或目录.<br>";
  222. }
  223. endif;
  224. ?>
  225.   </form>
  226.   <div id="footer">
  227.   <p><a href="http://ihacklog.com/" target="_blank">荒野无灯</a> (修改)  &nbsp;&nbsp;&nbsp;&nbsp;<a href="javascript:;" onclick="scrollTo(0,0);" title="返回顶部">TOP</a></p>
  228.   </div>