一、代码
class ZipFolder { private $zip = null; private $root_path = null; public function __construct() { $this->zip = new ZipArchive(); } /** * 开始压缩文件 * @param $real_path 需要压缩的路径 * @param $save_path 压缩后的文件路径 * @throws Exception */ public function zip($real_path, $save_path) { if (empty($real_path) || !is_dir($real_path) || empty($save_path)) { throw new Exception('参数错误'); } if ($this->zip->open($save_path, ZipArchive::CREATE) === true) { $this->root_path = substr($real_path, 0, strlen($real_path) - strrpos($real_path, '/') + 1); $this->addFileToZip($real_path); } } /** * 解压zip文件 * @param $filename 要解压的文件 * @param string $path 解压的文件目录 */ public function unZip($filename, $path = './') { //打开压缩包 $resource = zip_open($filename); $i = 1; //遍历读取压缩包里面的一个个文件 while ($dir_resource = @zip_read($resource)) { //如果能打开则继续 if (zip_entry_open($resource,$dir_resource)) { //获取当前项目的名称,即压缩包里面当前对应的文件名 $file_name = $path.zip_entry_name($dir_resource); //以最后一个“/”分割,再用字符串截取出路径部分 $file_path = substr($file_name,0,strrpos($file_name, "/")); //如果路径不存在,则创建一个目录,true表示可以创建多级目录 if(!is_dir($file_path)){ mkdir($file_path,0777,true); } //如果不是目录,则写入文件 if(!is_dir($file_name)){ //读取这个文件 $file_size = zip_entry_filesize($dir_resource); //最大读取6M,如果文件过大,跳过解压,继续下一个 if($file_size<(1024*1024*30)){ $file_content = zip_entry_read($dir_resource,$file_size); file_put_contents($file_name,$file_content); }else{ echo "<p> ".$i++." 此文件已被跳过,原因:文件过大, -> ".iconv("gb2312","utf-8",$file_name)." </p>"; } } //关闭当前 zip_entry_close($dir_resource); } } //关闭压缩包 @zip_close($resource); } /** * 递归添加文件到压缩中 * @param $real_path 需要压缩的路径 */ private function addFileToZip($real_path) { $handler = opendir($real_path); while (($filename = readdir($handler)) !== false) { if ($filename != "." && $filename != "..") { $new_filename = $real_path . "/" . $filename; $local_filename = str_replace($this->root_path, '', $new_filename); if (is_dir($new_filename)) { //创建空文件夹 $this->zip->addEmptyDir($local_filename); $this->addFileToZip($new_filename); } else { //将文件加入zip对象 $this->zip->addFile($new_filename, $local_filename); } } } @closedir($real_path); } public function closeZip() { $this->zip->close(); } }
二、示例
$zip = new ZipFolder(); $zip->zip('../../test', './test.zip'); $zip->unZip('./test.zip'); $zip->closeZip();