首頁 後端開發 php教程 php工具类之【zip压缩文件处置类】

php工具类之【zip压缩文件处置类】

Jun 13, 2016 pm 12:04 PM
data file header size

php工具类之【zip压缩文件处理类】

class PHPZip{	private $ctrl_dir = array();        	private $datasec = array(); 	private $old_offset = 0;       	private $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";  		/**         	 * 压缩部分--遍历指定文件夹       	 * @param String $path--文件夹路径	 * @return array--文件夹内容列表	 ****/       	function visitFile($path){		$fileList = array();     		$path = str_replace("\\","/",$path);     		$fdir = dir($path);                    		while(($file = $fdir->read()) !== false){                			if($file == '.' || $file == '..'){ 				continue; 			}                        			$pathSub    = preg_replace("*/{2,}*", "/", $path."/".$file);  // 替换多个反斜杠                			$fileList[] = is_dir($pathSub) ? $pathSub."/" : $pathSub;                			if(is_dir($pathSub)){ 				$this->visitFile($pathSub); 			}            		}            		$fdir->close();            		return $fileList;        	}        	/**	 * 压缩到服务器	 * @param String $dir--需压缩的文件所在目录	 * @param String $saveName--ZIP压缩文件名	 * @return boolean--是否压缩成功	 * */	public function Zip($dir, $saveName){            		if(@!function_exists('gzcompress')){ 			return false; 		}                		ob_end_clean();            		$filelist = $this->visitFile($dir);            		if(count($filelist) == 0){ 			return false; 		}                		foreach($filelist as $file){                			if(!file_exists($file) || !is_file($file)){ 				continue; 			}                                			$fd = fopen($file, "rb");                			$content  = @fread($fd, filesize($file));                			fclose($fd);                						// 1.删除$dir的字符(./folder/file.txt删除./folder/)                			// 2.如果存在/就删除(/file.txt删除/)                			$file = substr($file, strlen($dir));                			if(substr($file, 0, 1) == "\\" || substr($file, 0, 1) == "/"){ 				$file = substr($file, 1); 			}                                			$this->addFile($content, $file);            		}            		$out = $this->file();               		$fp = fopen($saveName, "wb");            		fwrite($fp,$out,strlen($out));            		fclose($fp);  		return true;      	}       	/**	 * 压缩并直接下载	 * @param String $dir--需压缩的文件所在目录	 */	public function ZipAndDownload($dir){            		if(@!function_exists('gzcompress')){ 			return; 		}                		ob_end_clean();            		$filelist = $this->visitFile($dir);            		if(count($filelist) == 0){ return; }                		foreach($filelist as $file){                			if(!file_exists($file) || !is_file($file)){ continue; }                                			$fd       = fopen($file, "rb");                			$content  = @fread($fd, filesize($file));                			fclose($fd);                    						// 1.删除$dir的字符(./folder/file.txt删除./folder/)                			// 2.如果存在/就删除(/file.txt删除/)                			$file = substr($file, strlen($dir));                			if(substr($file, 0, 1) == "\\" || substr($file, 0, 1) == "/"){ 				$file = substr($file, 1); 			}                                			$this->addFile($content, $file);            		}            		$out = $this->file();                		@header('Content-Encoding: none');            		@header('Content-Type: application/zip');            		@header('Content-Disposition: attachment ; filename=Farticle'.date("YmdHis", time()).'.zip');            		@header('Pragma: no-cache');            		@header('Expires: 0');            		print($out);        	} 	// ------------------------------------------------------ //     	// $archive   = new PHPZip();        	// $zipfile   = "ZIP压缩文件名";        	// $savepath  = "解压缩目录名";        	// $zipfile   = $unzipfile;        	// $savepath  = $unziptarget;        	// $array     = $archive->GetZipInnerFilesInfo($zipfile);        	// $filecount = 0;        	// $dircount  = 0;        	// $failfiles = array();        	// set_time_limit(0);  	// 修改为不限制超时时间(默认为30秒)       	// for($i=0; $i<count($array); $i++) {        	//     if($array[$i][folder] == 0){        	//         if($archive->unZip($zipfile, $savepath, $i) > 0){        	//             $filecount++;        	//         }else{        	//             $failfiles[] = $array[$i][filename];        	//         }        	//     }else{        	//         $dircount++;        	//     }        	// }        	// set_time_limit(30);        	// printf("文件夹:%d    解压文件:%d    失败:%d<br>\r\n", $dircount, $filecount, count($failfiles));        	// if(count($failfiles) > 0){        	//    foreach($failfiles as $file){        	//        printf("&middot;%s<br>\r\n", $file);        	//    }        	// }        	// ------------------------------------------------------//       	 public function unZip($zipfile, $to, $index = Array(-1)){            	 	$ok  = 0;            	 	$zip = @fopen($zipfile, 'rb');            	 	if(!$zip){ return(-1); }                        	 	$cdir      = $this->ReadCentralDir($zip, $zipfile);            	 	$pos_entry = $cdir['offset'];                        	 	if(!is_array($index)){ $index = array($index); }            	 	for($i=0; $index[$i]; $i++){                	 		if(intval($index[$i]) != $index[$i] || $index[$i] > $cdir['entries']){                    	 			return(-1);                	 		}            	 	}                        	 	for($i=0; $i<$cdir['entries']; $i++){                	 		@fseek($zip, $pos_entry);                	 		$header          = $this->ReadCentralFileHeaders($zip);                	 		$header['index'] = $i;                	 		$pos_entry       = ftell($zip);                	 		@rewind($zip);                	 		fseek($zip, $header['offset']);                	 		if(in_array("-1", $index) || in_array($i, $index)){                    	 			$stat[$header['filename']] = $this->ExtractFile($header, $to, $zip);                	 		}            	 	}                        	 	fclose($zip);            	 	return $stat;        	 }     	 // ------------------------------------------------------ //        	 // #获取被压缩文件的信息        //        	 // $archive = new PHPZip();        	 // $array = $archive->GetZipInnerFilesInfo(ZIP压缩文件名);        	 // for($i=0; $i<count($array); $i++) {        	 //     printf("<b>&middot;%s</b><br>\r\n", $array[$i][filename]);        	 //     foreach($array[$i] as $key => $value)        	 //         printf("%s => %s<br>\r\n", $key, $value);        	 //     print "\r\n<p>------------------------------------<p>\r\n\r\n";        	 // }        	 // ------------------------------------------------------ //        	 public function GetZipInnerFilesInfo($zipfile){            	 	$zip = @fopen($zipfile, 'rb');            	 	if(!$zip){ return(0); }            	 	$centd = $this->ReadCentralDir($zip, $zipfile);                        	 	@rewind($zip);            	 	@fseek($zip, $centd['offset']);            	 	$ret = array();            	 	for($i=0; $i<$centd['entries']; $i++){                	 		$header          = $this->ReadCentralFileHeaders($zip);                	 		$header['index'] = $i;                	 		$info = array('filename'      => $header['filename'],// 文件名                    	 					'stored_filename' => $header['stored_filename'],            // 压缩后文件名                    	 					'size'            => $header['size'],                       // 大小                    	 					'compressed_size' => $header['compressed_size'],            // 压缩后大小                   	 		            'crc'             => strtoupper(dechex($header['crc'])),    // CRC32                    	 					'mtime'           => date("Y-m-d H:i:s",$header['mtime']),  // 文件修改时间                    	 					'comment'         => $header['comment'],                    // 注释                    	 					'folder'          => ($header['external'] == 0x41FF0010 || $header['external'] == 16) ? 1 : 0,  // 是否为文件夹                    	 					'index'           => $header['index'],                      // 文件索引                    	 					'status'          => $header['status']                      // 状态                	 		);               	 		$ret[] = $info;                	 		unset($header);            	 	}            	 	fclose($zip);            	 	return $ret;        	 }                        	 // ------------------------------------------------------ //        	 // #获取压缩文件的注释        //        	 // $archive = new PHPZip();        	 // echo $archive->GetZipComment(ZIP压缩文件名);        	 // ------------------------------------------------------ //        	 public function GetZipComment($zipfile){            	 	$zip = @fopen($zipfile, 'rb');            	 	if(!$zip){ return(0); }            	 	$centd = $this->ReadCentralDir($zip, $zipfile);            	 	fclose($zip);            	 	return $centd[comment];        	 } 	 	private 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;           		}                		return (($timearray['year'] - 1980) << 25)| 				($timearray['mon'] << 21)| 				($timearray['mday'] << 16)| 				($timearray['hours'] << 11)| 				($timearray['minutes'] << 5)| 				($timearray['seconds'] >> 1);        	}                               	private function addFile($data, $filename, $time = 0){            		$filename = str_replace('\\', '/', $filename);                		$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";            		$fr      .= "\x00\x00";            		$fr      .= "\x08\x00";            		$fr      .= $hexdtime;            		$unc_len  = strlen($data);            		$crc      = crc32($data);            		$zdata    = gzcompress($data);            		$c_len    = strlen($zdata);            		$zdata    = substr(substr($zdata, 0, strlen($zdata) - 4), 2);            		$fr      .= pack('V', $crc);            		$fr      .= pack('V', $c_len);            		$fr      .= pack('V', $unc_len);            		$fr      .= pack('v', strlen($filename));            		$fr      .= pack('v', 0);            		$fr      .= $filename;                		$fr      .= $zdata;                		$fr      .= pack('V', $crc);            		$fr      .= pack('V', $c_len);            		$fr      .= pack('V', $unc_len);                		$this->datasec[] = $fr;            		$new_offset      = strlen(implode('', $this->datasec));                		$cdrec  = "\x50\x4b\x01\x02";            		$cdrec .= "\x00\x00";            		$cdrec .= "\x14\x00";            		$cdrec .= "\x00\x00";            		$cdrec .= "\x08\x00";            		$cdrec .= $hexdtime;            		$cdrec .= pack('V', $crc);            		$cdrec .= pack('V', $c_len);            		$cdrec .= pack('V', $unc_len);            		$cdrec .= pack('v', strlen($filename) );            		$cdrec .= pack('v', 0 );            		$cdrec .= pack('v', 0 );            		$cdrec .= pack('v', 0 );            		$cdrec .= pack('v', 0 );            		$cdrec .= pack('V', 32 );                		$cdrec .= pack('V', $this->old_offset );            		$this->old_offset = $new_offset;                		$cdrec .= $filename;            		$this->ctrl_dir[] = $cdrec;        	}                        	      	private function file(){            		$data    = implode('', $this->datasec);            		$ctrldir = implode('', $this->ctrl_dir);                		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";        	}                    	                	                                               	/**********************************************************         	 *解压部分       	 *ReadCentralDir($zip, $zipfile)        	 [email&#160;protected] [email&#160;protected]($zipfile, 'rb')打开的        	 [email&#160;protected] $zipfile是zip文件的路径        	 **/       	private function ReadCentralDir($zip, $zipfile){            		$size     = filesize($zipfile);            		$max_size = ($size < 277) ? $size : 277;                        		@fseek($zip, $size - $max_size);            		$pos   = ftell($zip);            		$bytes = 0x00000000;                        		while($pos < $size){                			$byte  = @fread($zip, 1);                			$bytes = ($bytes << 8) | Ord($byte);                			$pos++;			if ('Linux' == PHP_OS && substr(dechex($bytes),-8,8) == '504b0506') { break; }			if($bytes == 0x504b0506){ break; }            		}                        		$data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', fread($zip, 18));            		$centd['comment'] = ($data['comment_size'] != 0) ? fread($zip, $data['comment_size']) : '';  		// 注释            		$centd['entries']      = $data['entries'];            		$centd['disk_entries'] = $data['disk_entries'];            		$centd['offset']       = $data['offset'];            		$centd['disk_start']   = $data['disk_start'];            		$centd['size']         = $data['size'];            		$centd['disk']         = $data['disk'];            		return $centd;        	}                        	private function ReadCentralFileHeaders($zip){            		$binary_data = fread($zip, 46);            		$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);            		$header['filename'] = ($header['filename_len'] != 0) ? fread($zip, $header['filename_len']) : '';            		$header['extra']    = ($header['extra_len']    != 0) ? fread($zip, $header['extra_len'])    : '';            		$header['comment']  = ($header['comment_len']  != 0) ? fread($zip, $header['comment_len'])  : '';                		if($header['mdate'] && $header['mtime']){                			$hour    = ($header['mtime']  & 0xF800) >> 11;                			$minute  = ($header['mtime']  & 0x07E0) >> 5;                			$seconde = ($header['mtime']  & 0x001F) * 2;                			$year    = (($header['mdate'] & 0xFE00) >> 9) + 1980;                			$month   = ($header['mdate']  & 0x01E0) >> 5;                			$day     = $header['mdate']   & 0x001F;                			$header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);            		} else {                			$header['mtime'] = time();            		}            		$header['stored_filename'] = $header['filename'];            		$header['status'] = 'ok';            		if(substr($header['filename'], -1) == '/'){ 			$header['external'] = 0x41FF0010; }  // 判断是否文件夹       			if ('Linux' == PHP_OS){	 	$header['filename']=iconv("gb2312", "UTF-8", $header['filename']);	 	$header['extra']=iconv("gb2312", "UTF-8", $header['extra']);	 	$header['stored_filename']=iconv("gb2312", "UTF-8", $header['stored_filename']);     			}			return $header;        	}                	private function ReadFileHeader($zip){            		$binary_data = fread($zip, 30);            		$data        = unpack('vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $binary_data);                		$header['filename']        = fread($zip, $data['filename_len']);            		$header['extra']           = ($data['extra_len'] != 0) ? fread($zip, $data['extra_len']) : '';            		$header['compression']     = $data['compression'];            		$header['size']            = $data['size'];            		$header['compressed_size'] = $data['compressed_size'];            		$header['crc']             = $data['crc'];            		$header['flag']            = $data['flag'];            		$header['mdate']           = $data['mdate'];            		$header['mtime']           = $data['mtime'];   		if ('Linux' == PHP_OS){	 	$header['filename']=iconv("gb2312", "UTF-8", $header['filename']);	 	$header['extra']=iconv("gb2312", "UTF-8", $header['extra']);	 	$header['stored_filename']=iconv("gb2312", "UTF-8", $header['stored_filename']);     			}        		if($header['mdate'] && $header['mtime']){                			$hour    = ($header['mtime']  & 0xF800) >> 11;                			$minute  = ($header['mtime']  & 0x07E0) >> 5;                			$seconde = ($header['mtime']  & 0x001F) * 2;                			$year    = (($header['mdate'] & 0xFE00) >> 9) + 1980;                			$month   = ($header['mdate']  & 0x01E0) >> 5;                			$day     = $header['mdate']   & 0x001F;                			$header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);            		}else{                			$header['mtime'] = time();            		}                		$header['stored_filename'] = $header['filename'];            		$header['status']          = "ok";            		return $header;        	}                	private function ExtractFile($header, $to, $zip){  		if ('Linux' == PHP_OS){	 	$header['filename']=iconv("gb2312", "UTF-8", $header['filename']);	 	$header['extra']=iconv("gb2312", "UTF-8", $header['extra']);	 	$header['stored_filename']=iconv("gb2312", "UTF-8", $header['stored_filename']);     			}    		$header = $this->readfileheader($zip);                        		if(substr($to, -1) != "/"){ $to .= "/"; }            		if([email&#160;protected]_dir($to)){ @mkdir($to, 0777); }                        		$pth = explode("/", dirname($header['filename']));            		for($i=0; isset($pth[$i]); $i++){                			if(!$pth[$i]){ continue; }                			$pthss .= $pth[$i]."/";                			if(!is_dir($to.$pthss)){ 				@mkdir($to.$pthss, 0777); 			}            		}                        		if(!($header['external'] == 0x41FF0010) && !($header['external'] == 16)){                			if($header['compression'] == 0){                    				$fp = @fopen($to.$header['filename'], 'wb');                    				if(!$fp){ return(-1); }                    				$size = $header['compressed_size'];                                        				while($size != 0){                        					$read_size   = ($size < 2048 ? $size : 2048);                        					$buffer      = fread($zip, $read_size);                        					$binary_data = pack('a'.$read_size, $buffer);                        					@fwrite($fp, $binary_data, $read_size);                        					$size       -= $read_size;                    				}                    				fclose($fp);                    				touch($to.$header['filename'], $header['mtime']);                                			}else{                                        				$fp = @fopen($to.$header['filename'].'.gz', 'wb');                    				if(!$fp){ return(-1); }                    				$binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($header['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));                                        				fwrite($fp, $binary_data, 10);                    				$size = $header['compressed_size'];                                        				while($size != 0){                        					$read_size   = ($size < 1024 ? $size : 1024);                        					$buffer      = fread($zip, $read_size);                        					$binary_data = pack('a'.$read_size, $buffer);                        					@fwrite($fp, $binary_data, $read_size);                        					$size       -= $read_size;                    				}                                        				$binary_data = pack('VV', $header['crc'], $header['size']);                    				fwrite($fp, $binary_data, 8);                    				fclose($fp);                                        				$gzp = @gzopen($to.$header['filename'].'.gz', 'rb') or die("Cette archive est compress!");                                        				if(!$gzp){ return(-2); }                    				$fp = @fopen($to.$header['filename'], 'wb');                    				if(!$fp){ return(-1); }                    				$size = $header['size'];                                        				while($size != 0){                        					$read_size   = ($size < 2048 ? $size : 2048);                        					$buffer      = gzread($gzp, $read_size);                        					$binary_data = pack('a'.$read_size, $buffer);                        					@fwrite($fp, $binary_data, $read_size);                        					$size       -= $read_size;                    				}                    				fclose($fp); 				gzclose($gzp);                                        				touch($to.$header['filename'], $header['mtime']);                    				@unlink($to.$header['filename'].'.gz');                			}            		}            		return true;        	}   }
登入後複製

?

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

使用java的File.length()函數取得檔案的大小 使用java的File.length()函數取得檔案的大小 Jul 24, 2023 am 08:36 AM

使用Java的File.length()函數取得檔案的大小檔案大小是在處理檔案作業時很常見的一個需求,Java提供了一個很方便的方法來取得檔案的大小,即使用File類別的length()方法。本文將介紹如何使用此方法來取得檔案的大小,並給出對應的程式碼範例。首先,我們需要建立一個File物件來表示我們想要取得大小的檔案。以下是建立File物件的方法:Filef

php blob怎麼轉file php blob怎麼轉file Mar 16, 2023 am 10:47 AM

php blob轉file的方法:1.建立一個php範例檔;2、透過「function blobToFile(blob) {return new File([blob], 'screenshot.png', { type: 'image/jpeg' })} 」方法實作Blob轉File即可。

鴻蒙原生應用隨機詩詞 鴻蒙原生應用隨機詩詞 Feb 19, 2024 pm 01:36 PM

想了解更多關於開源的內容,請造訪:51CTO鴻蒙開發者社群https://ost.51cto.com運行環境DAYU200:4.0.10.16SDK:4.0.10.15IDE:4.0.600一、建立應用程式點擊File- >newFile->CreateProgect。選擇模版:【OpenHarmony】EmptyAbility:填寫項目名,shici,應用包名com.nut.shici,應用儲存位置XXX(不要有中文,特殊字符,空格)。 CompileSDK10,Model:Stage。 Device

使用java的File.renameTo()函數重命名文件 使用java的File.renameTo()函數重命名文件 Jul 25, 2023 pm 03:45 PM

使用Java的File.renameTo()函數重命名檔案在Java程式設計中,我們經常需要對檔案進行重命名的操作。 Java提供了File類別來處理檔案操作,其中的renameTo()函數可以方便地重新命名檔案。本文將介紹如何使用Java的File.renameTo()函數來重新命名文件,並提供對應的程式碼範例。 File.renameTo()函數是File類別的一個方法,

SpringBoot怎麼透過Feign呼叫傳遞Header中參數 SpringBoot怎麼透過Feign呼叫傳遞Header中參數 May 16, 2023 pm 08:38 PM

【SpringBoot】透過Feign呼叫傳遞Header中參數如何透過Feign傳遞Header參數問題描述我們在SpringCloud中使用Feign請求另一個服務的Api介面時,有將Header中參數傳遞下去的需求,如果不做特殊處理,就會將Header中的參數遺失。解決方案方案一:透過@RequestHeader(name="headerName")來傳遞例如:Feign定義如下@FeignClient(name="service-name")pub

linux的header是什麼意思 linux的header是什麼意思 Jul 18, 2023 pm 03:34 PM

linux的header是指在文件或資料流中的開頭部分,用於包含關於內容的元數據,透過正確地編寫和使用Header文件,開發者能夠更好地利用系統資源,提高程式碼的可讀性和可維護性。

使用java的File.getParent()函數取得檔案的父路徑 使用java的File.getParent()函數取得檔案的父路徑 Jul 24, 2023 pm 01:40 PM

使用java的File.getParent()函數取得檔案的父路徑在Java程式設計中,我們經常需要操作檔案和資料夾。有時候,我們需要取得一個檔案的父路徑,也就是該檔案所在資料夾的路徑。 Java的File類別提供了getParent()方法用來取得檔案或資料夾的父路徑。 File類別是Java對檔案和資料夾的抽象表示,它提供了一系列操作檔案和資料夾的方法。其中,get

php header頭怎麼實現跳轉 php header頭怎麼實現跳轉 Dec 02, 2022 am 09:14 AM

php header實作跳轉的方法:1、使用「Header("Location:$url");」語法實作跳轉;2、使用if判斷式實作跳轉,其跳轉語句如「if($_COOKIE[" u_type"]){ header('location:register.php'); } else{ setcookie('u_type','1','86400*360');」。

See all articles