composer require chumper/zipper
use Chumper\Zipper\Zipper;
$zip = new Zipper();
// localFile 上传的 zip 压缩包地址 localPath 需要解压到的指定目录
$zip->make($localFile)->extractTo($localPath);
// 将vendor/chumper/zipper/src/Chumper/Zipper/Repositories/ZipRepository.php种的each方法修改为以下:
public function each($callback)
{
for ($i = 0; $i < $this->archive->numFiles; ++$i) {
//skip if folder
$stats = $this->archive->statIndex($i);
if ($stats['size'] === 0 && $stats['crc'] === 0) {
continue;
}
// 这里做了修改
$rawName = $this->archive->getNameIndex($i, ZipArchive::FL_ENC_RAW);
$encode = mb_detect_encoding($rawName, array("ASCII",'UTF-8',"GB2312","GBK",'BIG5'));
$rawName = iconv($encode, 'UTF-8', $rawName);
call_user_func_array($callback, [
$stats['name'], $rawName
]);
}
}
// 将vendor/chumper/zipper/src/Chumper/Zipper/Zipper.php中extractFilesInternal方法修改为以下:
private function extractFilesInternal($path, callable $matchingMethod)
{
$self = $this;
// 添加一个中文名参数
$this->repository->each(function ($fileName, $CNName) use ($path, $matchingMethod, $self) {
$currentPath = $self->getCurrentFolderWithTrailingSlash();
if (!empty($currentPath) && !starts_with($fileName, $currentPath)) {
return;
}
$filename = str_replace($self->getInternalPath(), '', $fileName);
if ($matchingMethod($filename)) {
$self->extractOneFileInternal($fileName, $CNName, $path);
}
});
}
// vendor/chumper/zipper/src/Chumper/Zipper/Zipper.php中extractOneFileInternal方法修改为以下:
private function extractOneFileInternal($fileName, $CNName, $path)
{
$tmpPath = str_replace($this->getInternalPath(), '', $CNName); // 用手动转码的中文文件名命名
// We need to create the directory first in case it doesn't exist
$dir = pathinfo($path.DIRECTORY_SEPARATOR.$tmpPath, PATHINFO_DIRNAME);
if (!$this->file->exists($dir) && !$this->file->makeDirectory($dir, 0755, true, true)) {
throw new \RuntimeException('Failed to create folders');
}
$toPath = $path.DIRECTORY_SEPARATOR.$tmpPath;
$fileStream = $this->getRepository()->getFileStream($fileName); // 用系统转码的文件名获取资源
$this->getFileHandler()->put($toPath, $fileStream);
}
如有侵权请邮件通知