乳房太大必要时要缩小_美美生活馆

PHP 真正的ZIP文件操作类

08月 31st, 2008 by Skylin

  在开发的过程中有时候我们可能需要使用到用zip来压缩和解压缩某个包,但是不是所有服务器我们都能控制(比如虚拟主机商提供的),所以我们可能在很多 环境下都不能使用PHP的ZIP扩展库,下面是我经常会用到的一个zip的PHP类,这里我的本意是想说我们大家可以研究下zip的格式,至于压缩数据其 实就是使用到了PHP的gz相关的函数。

 
  1. <?   
  2. class zip    
  3. {   
  4.    
  5. var $datasec$ctrl_dir = array();   
  6. var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";   
  7. var $old_offset = 0; var $dirs = Array(".");   
  8.    
  9. function get_List($zip_name)   
  10. {   
  11.   $zip = @fopen($zip_name‘rb’);   
  12.   if(!$zipreturn(0);   
  13.   $centd = $this->ReadCentralDir($zip,$zip_name);   
  14.    
  15.    @rewind($zip);   
  16.    @fseek($zip$centd['offset']);   
  17.    
  18.   for ($i=0; $i<$centd['entries']; $i++)   
  19.   {   
  20.    $header = $this->ReadCentralFileHeaders($zip);   
  21.    $header['index'] = $i;$info['filename'] = $header['filename'];   
  22.    $info['stored_filename'] = $header['stored_filename'];   
  23.    $info['size'] = $header['size'];
  24.    $info['compressed_size']=$header['compressed_size'];   
  25.    $info['crc'] = strtoupper(dechex$header['crc'] ));   
  26.    $info['mtime'] = $header['mtime']; $info['comment'] = $header['comment'];   
  27.    $info['folder'] = ($header['external']==0×41FF0010||$header['external']==16)?1:0;   
  28.    $info['index'] = $header['index'];$info['status'] = $header['status'];   
  29.    $ret[]=$info; unset($header);   
  30.   }   
  31. return $ret;   
  32. }   
  33. function Add($files,$compact)   
  34. {   
  35. if(!is_array($files[0])) $files=Array($files);   
  36.    
  37. for($i=0;$files[$i];$i++){   
  38.    $fn = $files[$i];   
  39.    if(!in_Array(dirname($fn[0]),$this->dirs))   
  40.     $this->add_Dir(dirname($fn[0]));   
  41.    if(basename($fn[0]))   
  42.     $ret[basename($fn[0])]=$this->add_File($fn[1],$fn[0],$compact);   
  43. }   
  44. return $ret;   
  45. }   
  46.    
  47. function get_file()   
  48. {   
  49.   $data = implode($this -> datasec);   
  50.   $ctrldir = implode($this -> ctrl_dir);   
  51.    
  52.   return $data . $ctrldir . $this -> eof_ctrl_dir .   
  53.    pack(‘v’, sizeof($this -> ctrl_dir)).pack(‘v’, sizeof($this -> ctrl_dir)).   
  54.    pack(‘V’strlen($ctrldir)) . pack(‘V’strlen($data)) . "\x00\x00";   
  55. }   
  56.    
  57. function add_dir($name)    
  58. {    
  59.   $name = str_replace("\\", "/", $name);    
  60.   $fr = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00";    
  61.    
  62.   $fr .= pack("V",0).pack("V",0).pack("V",0).pack("v"strlen($name) );    
  63.   $fr .= pack("v", 0 ).$name.pack("V", 0).pack("V", 0).pack("V", 0);    
  64.   $this -> datasec[] = $fr;   
  65.    
  66.   $new_offset = strlen(implode(""$this->datasec));    
  67.    
  68.   $cdrec = "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00";    
  69.   $cdrec .= pack("V",0).pack("V",0).pack("V",0).pack("v"strlen($name) );    
  70.   $cdrec .= pack("v", 0 ).pack("v", 0 ).pack("v", 0 ).pack("v", 0 );    
  71.   $ext = "\xff\xff\xff\xff";    
  72.   $cdrec .= pack("V", 16 ).pack("V"$this -> old_offset ).$name;    
  73.    
  74.   $this -> ctrl_dir[] = $cdrec;    
  75.   $this -> old_offset = $new_offset;    
  76.   $this -> dirs[] = $name;   
  77. }   
  78.    
  79. function add_File($data$name$compact = 1)   
  80. {   
  81.   $name     = str_replace(‘\\’, ’/’, $name);   
  82.   $dtime    = dechex($this->DosTime());   
  83.    
  84.   $hexdtime = ‘\x’ . $dtime[6] . $dtime[7].‘\x’.$dtime[4] . $dtime[5]   
  85.     . ‘\x’ . $dtime[2] . $dtime[3].‘\x’.$dtime[0].$dtime[1];   
  86.   eval(‘$hexdtime = "’ . $hexdtime . ‘";’);   
  87.    
  88.   if($compact)   
  89.   $fr = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$hexdtime;   
  90.   else $fr = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00".$hexdtime;   
  91.   $unc_len = strlen($data); $crc = crc32($data);   
  92.    
  93.   if($compact){   
  94.     $zdata = gzcompress($data); $c_len = strlen($zdata);   
  95.     $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);   
  96.   }else{   
  97.     $zdata = $data;   
  98.   }   
  99.   $c_len=strlen($zdata);   
  100.   $fr .= pack(‘V’$crc).pack(‘V’$c_len).pack(‘V’$unc_len);   
  101.   $fr .= pack(‘v’strlen($name)).pack(‘v’, 0).$name.$zdata;   
  102.    
  103.   $fr .= pack(‘V’$crc).pack(‘V’$c_len).pack(‘V’$unc_len);   
  104.    
  105.   $this -> datasec[] = $fr;   
  106.   $new_offset        = strlen(implode($this->datasec));   
  107.   if($compact)   
  108.        $cdrec = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00";   
  109.   else $cdrec = "\x50\x4b\x01\x02\x14\x00\x0a\x00\x00\x00\x00\x00";   
  110.   $cdrec .= $hexdtime.pack(‘V’$crc).pack(‘V’$c_len).pack(‘V’$unc_len);   
  111.   $cdrec .= pack(‘v’strlen($name) ).pack(‘v’, 0 ).pack(‘v’, 0 );   
  112.   $cdrec .= pack(‘v’, 0 ).pack(‘v’, 0 ).pack(‘V’, 32 );   
  113.   $cdrec .= pack(‘V’$this -> old_offset );   
  114.    
  115.   $this -> old_offset = $new_offset;   
  116.   $cdrec .= $name;   
  117.   $this -> ctrl_dir[] = $cdrec;   
  118.   return true;   
  119. }   
  120.    
  121. function DosTime() {   
  122.   $timearray = getdate();   
  123.   if ($timearray['year'] < 1980) {   
  124.     $timearray['year'] = 1980; $timearray['mon'] = 1;   
  125.     $timearray['mday'] = 1; $timearray['hours'] = 0;   
  126.     $timearray['minutes'] = 0; $timearray['seconds'] = 0;   
  127.   }   
  128.   return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) |     
  129.    ($timearray['mday'] << 16) | ($timearray['hours'] << 11) |    
  130.    ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);   
  131. }   
  132.    
  133. function Extract ( $zn$to$index = Array(-1) )   
  134. {   
  135.   $ok = 0; $zip = @fopen($zn,‘rb’);   
  136.   if(!$zipreturn(-1);   
  137.   $cdir = $this->ReadCentralDir($zip,$zn);   
  138.   $pos_entry = $cdir['offset'];   
  139.    
  140.   if(!is_array($index)){ $index = array($index);  }   
  141.   for($i=0; $index[$i];$i++){   
  142.     if(intval($index[$i])!=$index[$i]||$index[$i]>$cdir['entries'])   
  143.      return(-1);   
  144.   }   
  145.    
  146.   for ($i=0; $i<$cdir['entries']; $i++)   
  147.   {   
  148.     @fseek($zip$pos_entry);   
  149.     $header = $this->ReadCentralFileHeaders($zip);   
  150.     $header['index'] = $i$pos_entry = ftell($zip);   
  151.     @rewind($zip); fseek($zip$header['offset']);   
  152.     if(in_array("-1",$index)||in_array($i,$index))   
  153.      $stat[$header['filename']]=$this->ExtractFile($header$to$zip);   
  154.         
  155.   }   
  156.   fclose($zip);   
  157.   return $stat;   
  158. }   
  159.    
  160. function ReadFileHeader($zip)   
  161. {    
  162.    $binary_data = fread($zip, 30);   
  163.    $data = unpack(‘vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/
  164.            Vcompressed_size/Vsize/vfilename_len/vextra_len’$binary_data);   
  165.    
  166.    $header['filename'] = fread($zip$data['filename_len']);   
  167.    if ($data['extra_len'] != 0) {   
  168.      $header['extra'] = fread($zip$data['extra_len']);   
  169.    } else { $header['extra'] = ; }   
  170.    
  171.    $header['compression'] = $data['compression'];$header['size'] = $data['size'];   
  172.    $header['compressed_size'] = $data['compressed_size'];   
  173.    $header['crc'] = $data['crc']; $header['flag'] = $data['flag'];   
  174.    $header['mdate'] = $data['mdate'];$header['mtime'] = $data['mtime'];   
  175.    
  176.    if ($header['mdate'] && $header['mtime']){   
  177.     $hour=($header['mtime']&0xF800)>>11;$minute=($header['mtime']&0×07E0)>>5;   
  178.     $seconde=($header['mtime']&0×001F)*2;$year=(($header['mdate']&0xFE00)>>9)+1980;   
  179.     $month=($header['mdate']&0×01E0)>>5;$day=$header['mdate']&0×001F;   
  180.     $header['mtime'] = mktime($hour$minute$seconde$month$day$year);   
  181.    }else{$header['mtime'] = time();}   
  182.    
  183.    $header['stored_filename'] = $header['filename'];   
  184.    $header['status'] = "ok";   
  185.    return $header;   
  186. }   
  187.    
  188. function ReadCentralFileHeaders($zip){   
  189.    $binary_data = fread($zip, 46);   
  190.    $header = unpack(‘vchkid/vid/vversion/vversion_extracted/vflag/vcompression/vmtime/
  191.       vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/
  192.       vinternal/Vexternal/Voffset’$binary_data);   
  193.    
  194.    if ($header['filename_len'] != 0)   
  195.      $header['filename'] = fread($zip,$header['filename_len']);   
  196.    else $header['filename'] = ;   
  197.    
  198.    if ($header['extra_len'] != 0)   
  199.      $header['extra'] = fread($zip$header['extra_len']);   
  200.    else $header['extra'] = ;   
  201.    
  202.    if ($header['comment_len'] != 0)   
  203.      $header['comment'] = fread($zip$header['comment_len']);   
  204.    else $header['comment'] = ;   
  205.    
  206.    if ($header['mdate'] && $header['mtime'])   
  207.    {   
  208.      $hour = ($header['mtime'] & 0xF800) >> 11;   
  209.      $minute = ($header['mtime'] & 0×07E0) >> 5;   
  210.      $seconde = ($header['mtime'] & 0×001F)*2;   
  211.      $year = (($header['mdate'] & 0xFE00) >> 9) + 1980;   
  212.      $month = ($header['mdate'] & 0×01E0) >> 5;   
  213.      $day = $header['mdate'] & 0×001F;   
  214.      $header['mtime'] = mktime($hour$minute$seconde$month$day$year);   
  215.    } else {   
  216.      $header['mtime'] = time();   
  217.    }   
  218.    $header['stored_filename'] = $header['filename'];   
  219.    $header['status'] = ‘ok’;   
  220.    if (substr($header['filename'], -1) == ‘/’)   
  221.      $header['external'] = 0×41FF0010;   
  222.    return $header;   
  223. }   
  224.    
  225. function ReadCentralDir($zip,$zip_name)   
  226. {   
  227. $size = filesize($zip_name);   
  228. if ($size < 277) $maximum_size = $size;   
  229. else $maximum_size=277;   
  230.    
  231. @fseek($zip$size-$maximum_size);   
  232. $pos = ftell($zip); $bytes = 0×00000000;   
  233.    
  234. while ($pos < $size)   
  235. {   
  236.    $byte = @fread($zip, 1); $bytes=($bytes << 8) | Ord($byte);   
  237.    if ($bytes == 0×504b0506){ $pos++; break; } $pos++;   
  238. }   
  239.    
  240. $data=unpack(‘vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size’,
  241.               fread($zip,18));   
  242.    
  243.    
  244. if ($data['comment_size'] != 0)   
  245.    $centd['comment'] = fread($zip$data['comment_size']);   
  246.    else $centd['comment'] = $centd['entries'] = $data['entries'];   
  247. $centd['disk_entries'] = $data['disk_entries'];   
  248. $centd['offset'] = $data['offset'];$centd['disk_start'] = $data['disk_start'];   
  249. $centd['size'] = $data['size'];  $centd['disk'] = $data['disk'];   
  250. return $centd;   
  251. }   
  252.    
  253. function ExtractFile($header,$to,$zip)   
  254. {   
  255.   $header = $this->readfileheader($zip);   
  256.    
  257.   if(substr($to,-1)!="/"$to.="/";   
  258.   if(!@is_dir($to)) @mkdir($to,0777);   
  259.    
  260.   $pth = explode("/",dirname($header['filename']));   
  261.   for($i=0;isset($pth[$i]);$i++){   
  262.     if(!$pth[$i]) continue;$pthss.=$pth[$i]."/";   
  263.     if(!is_dir($to.$pthss)) @mkdir($to.$pthss,0777);   
  264.   }   
  265. if (!($header['external']==0×41FF0010)&&!($header['external']==16))   
  266. {   
  267.   if ($header['compression']==0)   
  268.   {   
  269.    $fp = @fopen($to.$header['filename'], ‘wb’);   
  270.    if(!$fpreturn(-1);   
  271.    $size = $header['compressed_size'];   
  272.    
  273.    while ($size != 0)   
  274.    {   
  275.      $read_size = ($size < 2048 ? $size : 2048);   
  276.      $buffer = fread($zip$read_size);   
  277.      $binary_data = pack(‘a’.$read_size$buffer);   
  278.      @fwrite($fp$binary_data$read_size);   
  279.      $size -= $read_size;   
  280.    }   
  281.    fclose($fp);   
  282.    touch($to.$header['filename'], $header['mtime']);   
  283.    
  284. }else{   
  285.   $fp = @fopen($to.$header['filename'].‘.gz’,‘wb’);   
  286.   if(!$fpreturn(-1);   
  287.   $binary_data = pack(‘va1a1Va1a1′, 0×8b1f, Chr($header['compression']),   
  288.     Chr(0×00), time(), Chr(0×00), Chr(3));   
  289.    
  290.   fwrite($fp$binary_data, 10);   
  291.   $size = $header['compressed_size'];   
  292.    
  293.   while ($size != 0)   
  294.   {   
  295.     $read_size = ($size < 1024 ? $size : 1024);   
  296.     $buffer = fread($zip$read_size);   
  297.     $binary_data = pack(‘a’.$read_size$buffer);   
  298.     @fwrite($fp$binary_data$read_size);   
  299.     $size -= $read_size;   
  300.   }   
  301.    
  302.   $binary_data = pack(‘VV’$header['crc'], $header['size']);   
  303.   fwrite($fp$binary_data,8); fclose($fp);   
  304.    
  305.   $gzp = @gzopen($to.$header['filename'].‘.gz’,‘rb’or die("Cette archive est 
  306.             compress");   
  307.    if(!$gzpreturn(-2);   
  308.   $fp = @fopen($to.$header['filename'],‘wb’);   
  309.   if(!$fpreturn(-1);   
  310.   $size = $header['size'];   
  311.    
  312.   while ($size != 0)   
  313.   {   
  314.     $read_size = ($size < 2048 ? $size : 2048);   
  315.     $buffer = gzread($gzp$read_size);   
  316.     $binary_data = pack(‘a’.$read_size$buffer);   
  317.     @fwrite($fp$binary_data$read_size);   
  318.     $size -= $read_size;   
  319.   }   
  320.   fclose($fp); gzclose($gzp);   
  321.    
  322.   touch($to.$header['filename'], $header['mtime']);   
  323.   @unlink($to.$header['filename'].‘.gz’);   
  324.    
  325. }}   
  326. return true;   
  327. }   
  328. }   
  329. ?>    

文件解压

 

 
  1. <?   
  2. $zipfile="a.zip"//zip 文件名   
  3. $i=1;             //这个是zip->get_list的时候文件对应的 [index] 号(必须是文件,也就是说 [folder]=0 的才可以)   
  4. $path="filesinzip";  //zip文件解压到的目录   
  5. include("zip.class.php");   
  6. $zip = new Zip;   
  7.    
  8. if ($zip->Extract($zipfile,$path,$i)) echo "ok"else echo "error";   
  9.    
  10. ?>    

 

压缩文件

 

 
  1. <?   
  2. include("zip.class.php");   
  3. $zip = new Zip;   
  4. $zipfile="zip.php";       //要压缩的文件名   
  5. $key="a.zip";             //生成的zip 文件名   
  6. $filename="me/me.php";    //zip文件中的文件名,可以和$zipfile不同   
  7. $filesize=@filesize($zipfile);    
  8.    
  9. $fp=@fopen($zipfile,rb);    
  10. $zipfilecontent=Array($filename,@fread($fp,$filesize));     
  11. @fclose($fp);   
  12. $zip->Add($zipfilecontent,1);  //可以多次执行 $zip->Add 来添加多个文件   
  13.    
  14. if(@fputs(@fopen($key,"wb"),$zip->get_file())) //写入文件   
  15. echo "文件压缩成功!!";   
  16. else   
  17. echo "文件压缩失败!!";   
  18. ?>    

 

浏览zip文件

 

 
  1. <?   
  2. $zipfile="a.zip";  //要浏览的zip文件名   
  3. include("zip.class.php");   
  4. $zip = new Zip;   
  5. $l=$zip->get_list($zipfile);   
  6. print_r($l);   
  7. ?>  

 

 

Posted in PHP |

Leave a Comment