* Date: 2020/7/23 * Time: 17:56 */ namespace file; use think\Exception; /** * Zip 文件包工具 * * @author wengxianhu * @date 2013-08-05 */ class ZipHelper { protected $zip; protected $root; protected $ignored_names; public function __construct() { $this->zip = new \ZipArchive();//使用此扩展,linux需开启zlib,windows需取消php_zip.dll前的注释 } /** * 解压zip文件到指定文件夹 * * @access public * @param string $zipfile 压缩文件路径 * @param string $path 压缩包解压到的目标路径 * @return bool 解压成功返回 true 否则返回 false */ public function unzip($zipfile, $path) { if ($this->zip->open($zipfile) === true) { $file_tmp = @fopen($zipfile, "rb"); $bin = fread($file_tmp, 15); //只读15字节 各个不同文件类型,头信息不一样。 fclose($file_tmp); /* 只针对zip的压缩包进行处理 */ if (true === $this->getTypeList($bin)) { $result = $this->zip->extractTo($path); $this->zip->close(); return $result; } else { return false; } } return false; } //解压,并处理中文 public function unzip_gbk($zipfile, $path) { if ($this->zip->open($zipfile) === true) { $fileNum = $this->zip->numFiles; for ($i = 0; $i < $fileNum; $i++) { $statInfo = $this->zip->statIndex($i, \ZipArchive::FL_ENC_RAW); $encode = mb_detect_encoding($statInfo['name'], array("ASCII", 'UTF-8', "GB2312", "GBK", 'BIG5')); $this->zip->renameIndex($i, mb_convert_encoding($statInfo['name'], 'utf-8', $encode)); } $this->zip->close(); $this->zip->open($zipfile); $file_tmp = @fopen($zipfile, "rb"); $bin = fread($file_tmp, 15); //只读15字节 各个不同文件类型,头信息不一样。 fclose($file_tmp); /* 只针对zip的压缩包进行处理 */ if (true === $this->getTypeList($bin)) { $result = $this->zip->extractTo($path); $this->zip->close(); return $result; } else { return false; } } return false; } /** * 创建压缩文件 * * @param string $zipfile 将要生成的压缩文件路径 * @param string $folder 将要被压缩的文件夹路径 * @param array $ignored 要忽略的文件列表 * @return bool 压缩包生成成功返回true 否则返回 false * @throws Exception */ public function zip($zipfile, $folder, $ignored = null) { $this->ignored_names = is_array($ignored) ? $ignored : $ignored ? array($ignored) : array(); if ($this->zip->open($zipfile, \ZipArchive::CREATE) !== true) { throw new Exception("cannot open <$zipfile>\n"); } if (is_file($folder)) { $this->zip->addFile($folder, basename($folder)); } elseif (is_dir($folder)) { $folder = substr($folder, -1) == '/' ? substr($folder, 0, strlen($folder) - 1) : $folder; if (strstr($folder, '/')) { $this->root = substr($folder, 0, strrpos($folder, '/') + 1); $folder = substr($folder, strrpos($folder, '/') + 1); } $this->createZip($folder); } return $this->zip->close(); } /** * 递归添加文件到压缩包 * * @access private * @param string $folder 添加到压缩包的文件夹路径 * @param string $parent 添加到压缩包的文件夹上级路径 * @return void */ private function createZip($folder, $parent = null) { $full_path = $this->root . $parent . $folder; $zip_path = $parent . $folder; $this->zip->addEmptyDir($zip_path); $dir = new \DirectoryIterator($full_path); foreach ($dir as $file) { if (!$file->isDot()) { $filename = $file->getFilename(); if (!in_array($filename, $this->ignored_names)) { if ($file->isDir()) { $this->createZip($filename, $zip_path . '/'); } else { $this->zip->addFile($full_path . '/' . $filename, $zip_path . '/' . $filename); } } } } } /** * 读取压缩包文件与目录列表 * * @access public * @param string $zipfile 压缩包文件 * @return array 文件与目录列表 */ public function fileList($zipfile) { $file_dir_list = array(); $file_list = array(); if ($this->zip->open($zipfile) == true) { for ($i = 0; $i < $this->zip->numFiles; $i++) { $numfiles = $this->zip->getNameIndex($i); if (preg_match('/\/$/i', $numfiles)) { $file_dir_list[] = $numfiles; } else { $file_list[] = $numfiles; } } } return array('files' => $file_list, 'dirs' => $file_dir_list); } /** * 得到文件头与文件类型映射表 * * @author wengxianhu * @date 2013-08-10 * @param $bin string 文件的二进制前一段字符 * @return boolean */ private function getTypeList($bin) { $array = array( array("504B0304", "zip") ); foreach ($array as $v) { $blen = strlen(pack("H*", $v[0])); //得到文件头标记字节数 $tbin = substr($bin, 0, intval($blen)); ///需要比较文件头长度 $temp1 = unpack("H*", $tbin); $temp2 = array_shift($temp1); if (strtolower($v[0]) == strtolower($temp2)) { return true; } } return false; } }