ZIP处理---H_zip.php

  1 <?php
2 /*************************************
3 * ZIP处理---H_zip.php
4 * 创建人: huang_xiang
5 * 创建时间:2008-12-25 9:29
6 * 更新时间:2009-2-18 13:37
7 * Email:yin273642232@163.com QQ:273642232
8 *************************************/
9 /*************************************
10 实例代码
11 include_once("H_zip.php"); //引入文件
12 $H_zip = new H_zip(); //产生对象
13 $H_zip -> get_List($zip_name); //返回:返回获取zip文件和文件夹列表,参数:$zip_name-zip文件名称;';
14 $H_zip -> Extract($zn,$to); //返回:解压zip,参数:$zn-zip文件名称:$to-解压到
15 $H_zip -> addfiles($H_file='test.zip',$H_flist); //返回:压缩zip,参数:$H_file-压缩zip文件名称:$Hfile-文件列表(array(array('1.txt','test.php'),array('1.txt','k/my.php')))
16
17 $H_zip_file = 't/example.zip';
18 $H_zip=new H_zip();
19 print_r($H_zip->Extract($H_zip_file,'./',array(-1))); //解压
20 print_r($H_zip->get_List($H_zip_file)); //返回列表
21 $H_zip -> addfiles($H_file='test.zip',array(array('1.txt','test.php'),array('1.txt','k/my.php'))); //压缩
22
23 *************************************/
24 //Start Class
25 class H_zip{
26 public $datasec, $ctrl_dir = array();
27 public $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
28 public $old_offset = 0;
29 public $dirs = Array(".");
30 public $H_temnm = '';
31
32 public function __construct(){
33 //当实例化一个对象的时候,这个对象的这个方法首先被调用
34 return '';
35 }
36 public function __destruct(){
37 //当删除一个对象或对象操作终止的时候,调用该方法
38 return '';
39 }
40 public function __get($key){
41 //当试图读取一个并不存在的属性的时候被调用
42 return '['.$key.'] Variable not find';
43 }
44 public function __set($key,$val){
45 //当试图向一个并不存在的属性写入值的时候被调用
46 return '['.$key.'] Variable not find';
47 }
48 public function __call($key,$args){
49 //当试图调用一个对象并不存在的方法时,调用该方法
50 return '['.$key.'] Function not find';
51 }
52 public function __toString(){
53 //当打印一个对象的时候被调用
54 return $this -> H_desce();
55 }
56 public function __clone(){
57 //当对象被克隆时,被调用
58 return "clone";
59 }
60 public function H_desce(){
61 //返回描述
62 $this -> H_desce .= '类名:H_zip-ZIP处理;';
63 $this -> H_desce .= '函数:get_List($zip_name),返回:返回获取zip文件和文件夹列表,参数:$zip_name-zip文件名称;';
64 $this -> H_desce .= '函数:Extract($zn,$to),返回:解压zip,参数:$zn-zip文件名称:$to-解压到;';
65 $this -> H_desce .= '函数:addfiles($H_file="test.zip",$H_flist),返回:压缩zip,参数:$H_file-压缩zip文件名称:$Hfile-文件列表(array(array("1.txt","test.php"),array("1.txt","k/my.php")));';
66 return $this -> H_desce;
67 }
68
69 public function get_List($zip_name){
70 $zip = @fopen($zip_name, 'rb');
71 if(!$zip) return(0);
72 $centd = $this -> ReadCentralDir($zip,$zip_name);
73 @rewind($zip);
74 @fseek($zip, $centd['offset']);
75 for ($i=0; $i<$centd['entries']; $i++){
76 $header = $this -> ReadCentralFileHeaders($zip);
77 $header['index'] = $i;$info['filename'] = $header['filename'];
78 $info['stored_filename'] = $header['stored_filename'];
79 $info['size'] = $header['size'];
80 $info['compressed_size'] = $header['compressed_size'];
81 $info['crc'] = strtoupper(dechex( $header['crc'] ));
82 $info['mtime'] = $header['mtime'];
83 $info['comment'] = $header['comment'];
84 $info['folder'] = ($header['external']==0x41FF0010||$header['external']==16)?1:0;
85 $info['index'] = $header['index'];
86 $info['status'] = $header['status'];
87 $ret[]=$info; unset($header);
88 }
89 return $ret;
90 }
91 public function Add($files,$compact){
92 if(!is_array($files[0])) $files = Array($files);
93 for($i=0;$files[$i];$i++){
94 $fn = $files[$i];
95 if(!in_Array(dirname($fn[0]),$this->dirs)) $this -> add_Dir(dirname($fn[0]));
96 if(basename($fn[0])) $ret[basename($fn[0])] = $this -> add_File($fn[1],$fn[0],$compact);
97 }
98 return $ret;
99 }
100 public function get_file(){
101 $data = implode('', $this -> datasec);
102 $ctrldir = implode('', $this -> ctrl_dir);
103 return $data.$ctrldir.$this -> eof_ctrl_dir.pack('v', sizeof($this -> ctrl_dir)).pack('v', sizeof($this -> ctrl_dir)).pack('V', strlen($ctrldir)).pack('V', strlen($data))."\x00\x00";
104 }
105 public function add_dir($name){
106 $name = str_replace("\\", "/", $name);
107 $fr = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00";
108 $fr .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name));
109 $fr .= pack("v", 0 ).$name.pack("V", 0).pack("V", 0).pack("V", 0);
110 $this -> datasec[] = $fr;
111 $new_offset = strlen(implode("", $this->datasec));
112 $cdrec = "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00";
113 $cdrec .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name));
114 $cdrec .= pack("v", 0 ).pack("v", 0 ).pack("v", 0 ).pack("v", 0 );
115 $ext = "\xff\xff\xff\xff";
116 $cdrec .= pack("V", 16 ).pack("V", $this -> old_offset ).$name;
117 $this -> ctrl_dir[] = $cdrec;
118 $this -> old_offset = $new_offset;
119 $this -> dirs[] = $name;
120 }
121 public function add_File($data, $name, $compact = 1){
122 $name = str_replace('\\', '/', $name);
123 $dtime = dechex($this->DosTime());
124 $hexdtime = '\x'.$dtime[6].$dtime[7].'\x'.$dtime[4].$dtime[5].'\x'.$dtime[2].$dtime[3].'\x'.$dtime[0].$dtime[1];
125 eval('$hexdtime = "'.$hexdtime.'";');
126 if($compact) $fr = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$hexdtime;
127 else $fr = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00".$hexdtime;
128 $unc_len = strlen($data);
129 $crc = crc32($data);
130 if($compact){
131 $zdata = gzcompress($data);
132 $c_len = strlen($zdata);
133 $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);
134 }else $zdata = $data;
135 $c_len=strlen($zdata);
136 $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len);
137 $fr .= pack('v', strlen($name)).pack('v', 0).$name.$zdata;
138 $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len);
139 $this -> datasec[] = $fr;
140 $new_offset = strlen(implode('', $this->datasec));
141 if($compact) $cdrec = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00";
142 else $cdrec = "\x50\x4b\x01\x02\x14\x00\x0a\x00\x00\x00\x00\x00";
143 $cdrec .= $hexdtime.pack('V', $crc).pack('V', $c_len).pack('V', $unc_len);
144 $cdrec .= pack('v', strlen($name) ).pack('v', 0 ).pack('v', 0 );
145 $cdrec .= pack('v', 0 ).pack('v', 0 ).pack('V', 32 );
146 $cdrec .= pack('V', $this -> old_offset );
147 $this -> old_offset = $new_offset;
148 $cdrec .= $name;
149 $this -> ctrl_dir[] = $cdrec;
150 return true;
151 }
152 public function DosTime(){
153 $timearray = getdate();
154 if($timearray['year'] < 1980){
155 $timearray['year'] = 1980;
156 $timearray['mon'] = 1;
157 $timearray['mday'] = 1;
158 $timearray['hours'] = 0;
159 $timearray['minutes'] = 0;
160 $timearray['seconds'] = 0;
161 }
162 return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21)|($timearray['mday'] << 16)|($timearray['hours'] << 11)|($timearray['minutes'] << 5)|($timearray['seconds'] >> 1);
163 }
164 public function Extract($zn, $to, $index = Array(-1)){
165 $ok = 0;
166 $zip = @fopen($zn,'rb');
167 if(!$zip) return(-1);
168 $cdir = $this->ReadCentralDir($zip,$zn);
169 $pos_entry = $cdir['offset'];
170 if(!is_array($index)) $index = array($index);
171 for($i=0; $index[$i];$i++){
172 if(intval($index[$i])!=$index[$i]||$index[$i]>$cdir['entries']) return(-1);
173 }
174 for ($i=0; $i<$cdir['entries']; $i++){
175 @fseek($zip, $pos_entry);
176 $header = $this->ReadCentralFileHeaders($zip);
177 $header['index'] = $i; $pos_entry = ftell($zip);
178 @rewind($zip);
179 fseek($zip, $header['offset']);
180 if(in_array("-1",$index)||in_array($i,$index)) $stat[$header['filename']]=$this->ExtractFile($header, $to, $zip);
181 }
182 fclose($zip);
183 return $stat;
184 }
185 public function ReadFileHeader($zip){
186 $binary_data = fread($zip, 30);
187 $data = unpack('vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $binary_data);
188 $header['filename'] = fread($zip, $data['filename_len']);
189 if($data['extra_len'] != 0){
190 $header['extra'] = fread($zip, $data['extra_len']);
191 }else $header['extra'] = '';
192 $header['compression'] = $data['compression'];
193 $header['size'] = $data['size'];
194 $header['compressed_size'] = $data['compressed_size'];
195 $header['crc'] = $data['crc'];
196 $header['flag'] = $data['flag'];
197 $header['mdate'] = $data['mdate'];
198 $header['mtime'] = $data['mtime'];
199 if($header['mdate'] && $header['mtime']){
200 $hour=($header['mtime']&0xF800)>>11;
201 $minute=($header['mtime']&0x07E0)>>5;
202 $seconde=($header['mtime']&0x001F)*2;
203 $year=(($header['mdate']&0xFE00)>>9)+1980;
204 $month=($header['mdate']&0x01E0)>>5;
205 $day=$header['mdate']&0x001F;
206 $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);
207 }else $header['mtime'] = time();
208 $header['stored_filename'] = $header['filename'];
209 $header['status'] = "ok";
210 return $header;
211 }
212 public function ReadCentralFileHeaders($zip){
213 $binary_data = fread($zip, 46);
214 $header = unpack('vchkid/vid/vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $binary_data);
215 if($header['filename_len'] != 0) $header['filename'] = fread($zip,$header['filename_len']);
216 else $header['filename'] = '';
217 if($header['extra_len'] != 0) $header['extra'] = fread($zip, $header['extra_len']);
218 else $header['extra'] = '';
219 if($header['comment_len'] != 0) $header['comment'] = fread($zip, $header['comment_len']);
220 else $header['comment'] = '';
221 if($header['mdate'] && $header['mtime']){
222 $hour = ($header['mtime'] & 0xF800) >> 11;
223 $minute = ($header['mtime'] & 0x07E0) >> 5;
224 $seconde = ($header['mtime'] & 0x001F)*2;
225 $year = (($header['mdate'] & 0xFE00) >> 9) + 1980;
226 $month = ($header['mdate'] & 0x01E0) >> 5;
227 $day = $header['mdate'] & 0x001F;
228 $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);
229 }else $header['mtime'] = time();
230 $header['stored_filename'] = $header['filename'];
231 $header['status'] = 'ok';
232 if (substr($header['filename'], -1) == '/') $header['external'] = 0x41FF0010;
233 return $header;
234 }
235 public function ReadCentralDir($zip,$zip_name){
236 $size = filesize($zip_name);
237 if($size < 277) $maximum_size = $size;
238 else $maximum_size=277;
239 @fseek($zip, $size-$maximum_size);
240 $pos = ftell($zip); $bytes = 0x00000000;
241 while ($pos < $size){
242 $byte = @fread($zip, 1); $bytes=($bytes << 8) | Ord($byte);
243 if($bytes == 0x504b0506){ $pos++; break; }
244 $pos++;
245 }
246 $data=unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size',fread($zip, 18));
247 if($data['comment_size'] != 0) $centd['comment'] = fread($zip, $data['comment_size']);
248 else $centd['comment'] = '';
249 $centd['entries'] = $data['entries'];
250 $centd['disk_entries'] = $data['disk_entries'];
251 $centd['offset'] = $data['offset'];
252 $centd['disk_start'] = $data['disk_start'];
253 $centd['size'] = $data['size'];
254 $centd['disk'] = $data['disk'];
255 return $centd;
256 }
257 public function ExtractFile($header,$to,$zip){
258 $header = $this->readfileheader($zip);
259 if(substr($to,-1)!="/") $to.="/";
260 if(!@is_dir($to)) @mkdir($to,0777);
261 $pth = explode("/",dirname($header['filename']));
262 for($i=0;isset($pth[$i]);$i++){
263 if(!$pth[$i]) continue;
264 if(!is_dir($to.$pth[$i])) @mkdir($to.$pth[$i],0777);
265 }
266 if(!($header['external']==0x41FF0010)&&!($header['external']==16)){
267 if($header['compression']==0){
268 $fp = @fopen($to.$header['filename'], 'wb');
269 if(!$fp) return(-1);
270 $size = $header['compressed_size'];
271 while ($size != 0){
272 $read_size = ($size < 2048 ? $size : 2048);
273 $buffer = fread($zip, $read_size);
274 $binary_data = pack('a'.$read_size, $buffer);
275 @fwrite($fp, $binary_data, $read_size);
276 $size -= $read_size;
277 }
278 fclose($fp);
279 touch($to.$header['filename'], $header['mtime']);
280 }else{
281 $fp = @fopen($to.$header['filename'].'.gz','wb');
282 if(!$fp) return(-1);
283 $binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($header['compression']),Chr(0x00), time(), Chr(0x00), Chr(3));
284 fwrite($fp, $binary_data, 10);
285 $size = $header['compressed_size'];
286 while ($size != 0){
287 $read_size = ($size < 1024 ? $size : 1024);
288 $buffer = fread($zip, $read_size);
289 $binary_data = pack('a'.$read_size, $buffer);
290 @fwrite($fp, $binary_data, $read_size);
291 $size -= $read_size;
292 }
293 $binary_data = pack('VV', $header['crc'], $header['size']);
294 fwrite($fp, $binary_data,8); fclose($fp);
295 $gzp = @gzopen($to.$header['filename'].'.gz','rb') or die("Cette archive est compress閑");
296 if(!$gzp) return(-2);
297 $fp = @fopen($to.$header['filename'],'wb');
298 if(!$fp) return(-1);
299 $size = $header['size'];
300 while ($size != 0){
301 $read_size = ($size < 2048 ? $size : 2048);
302 $buffer = gzread($gzp, $read_size);
303 $binary_data = pack('a'.$read_size, $buffer);
304 @fwrite($fp, $binary_data, $read_size);
305 $size -= $read_size;
306 }
307 fclose($fp); gzclose($gzp);
308 touch($to.$header['filename'], $header['mtime']);
309 @unlink($to.$header['filename'].'.gz');
310 }
311 }
312 return true;
313 }
314 public function addfiles($H_file='',$H_flist){
315 //压缩文件 $H_flist = array(array('old.txt','new.txt'));
316 $H_file = $H_file ==''?'temp_'.date('YmdHis').'.zip':$H_file;
317 if(!is_array($H_flist)) return false;
318 else{
319 foreach($H_flist as $H_key => $H_val){
320 //循环加入
321 $H_oldfl = '';
322 if(is_array($H_val)){
323 $H_oldfl = $H_val[0];
324 $H_newfl = $H_val[1];
325 }else $H_oldfl = $H_newfl = $H_val;
326 if($H_oldfl == '') continue;
327 $H_filesize = @filesize($H_oldfl);
328 $H_fp = @fopen($H_oldfl,'rb');
329 $H_file_cont = Array($H_newfl,@fread($H_fp,$H_filesize));
330 @fclose($H_fp);
331 $this -> Add($H_file_cont,1); //添加文件
332 }
333 $this -> H_temnm = $H_file;
334 if(@fputs(@fopen($H_file,"wb"),$this -> get_file())) return true;
335 else return false;
336 }
337 return true;
338 }
339 }//End Class
340 ?>

 

posted @ 2012-01-17 15:39  祥辉  阅读(414)  评论(0编辑  收藏  举报