解决php使用ZipArchive解压时中文乱码问题
使用php自带的ZipArchive来解压带中文文件名压缩包时会造成乱码,现象如下:
网上查阅基本上给出的答案大同小异,自己照着同样的方法试了都不能解决,下图是网上给出的方案:
经过摸索终于找到了解决方案,那就是弃用ZipArchive,选择其他的途径,经过比较我选择了“PhpZip”,优点是:纯php(不需要扩展和类),下面介绍安装方法:
composer安装:
composer require nelexa/zip如果选择版本的话:composer require nelexa/zip:^3.0 (3.0版本号)使用方法:
//解压文件$fileAddess = "压缩包地址";$toDir = "解压目录";$zipFile = new \PhpZip\ZipFile();$zipFile->openFile($fileAddess) // open archive from file->extractTo($toDir); // extract files to the specified directory$zipFile->close();
注释:(**如果安装好使用正常请忽略下面的注释内容**)1.我的压缩包放在共享盘里面连接的是smb地址,可能会出现报错:"Destination is not writable directory",这个坑已经踩过:打开ZipFile.php这个文件,找到“extractTo”方法,将“is_writable”函数改掉,或者去掉,然后再转换一下编码格式!,下面有注释的是我修改的内容!
/*** Extract the archive contents** Extract the complete archive or the given files to the specified destination.** @param string $destination Location where to extract the files.* @param array|string|null $entries The entries to extract. It accepts either*a single entry name or an array of names.* @return ZipFile* @throws ZipException*/public function extractTo($destination, $entries = null){if (!file_exists($destination)) {throw new ZipException("Destination " . $destination . " not found");}if (!is_dir($destination)) {throw new ZipException("Destination is not directory");}$is_really_writable = $this->is_really_writable($destination);if (!$is_really_writable) {throw new ZipException("Destination is not writable directory");}/*** @var ZipEntry[] $zipEntries*/if (!empty($entries)) {if (is_string($entries)) {$entries = (array)$entries;}if (is_array($entries)) {$entries = array_unique($entries);$flipEntries = array_flip($entries);$zipEntries = array_filter($this->centralDirectory->getEntries(),function ($zipEntry) use ($flipEntries) {/*** @var ZipEntry $zipEntry*/return isset($flipEntries[$zipEntry->getName()]);});}} else {$zipEntries = $this->centralDirectory->getEntries();}foreach ($zipEntries as $entry) {/******************************王天佑添加的逻辑start************************************/header("Content-type:text/html;charset=bgk");$entry_getName = iconv('GB2312', 'UTF-8//ignore',$entry->getName());//header("Content-type:text/html;charset=utf-8");/******************************王天佑添加的逻辑start************************************/$file = $destination . DIRECTORY_SEPARATOR . $entry_getName;if ($entry->isDirectory()) {if (!is_dir($file)) {if (!mkdir($file, 0755, true)) {throw new ZipException("Can not create dir " . $file);}chmod($file, 0755);touch($file, $entry->getTime());}continue;}$dir = dirname($file);if (!is_dir($dir)) {if (!mkdir($dir, 0755, true)) {throw new ZipException("Can not create dir " . $dir);}chmod($dir, 0755);touch($dir, $entry->getTime());}if (file_put_contents($file, $entry->getEntryContent()) === false) {throw new ZipException('Can not extract file ' . $entry_getName);}touch($file, $entry->getTime());}return $this;}//王天佑加的新逻辑,判断目录是否可写public function is_really_writable($file){if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE) {return is_writable($file);}if (is_dir($file)) {$file = rtrim($file, '/') . '/' . md5(mt_rand(1,100) . mt_rand(1,100));if (($fp = @fopen($file, "w+")) === FALSE) {return FALSE;}fclose($fp);@chmod($file, 0777);@unlink($file);} elseif (!is_file($file) OR ($fp = @fopen($file, "r+")) === FALSE) {fclose($fp);return FALSE;}return TRUE;}