【问题标题】:ZipArchive can't unzip files that ZipArchive zips in PHPZipArchive 无法解压缩 ZipArchive 在 PHP 中压缩的文件
【发布时间】:2014-03-28 01:03:57
【问题描述】:

尝试获取导入/导出功能。

  1. 使用包含文件的文件夹
  2. 使用 ZipArchive 在 PHP 中压缩文件夹
  3. 使用 ZipArchive 解压缩压缩文件夹
  4. 新建文件夹,但里面的文件不见了

    function unArchive(){
        $zip = new ZipArchive;
        $res = $zip->open('zipTest.zip');
        if ($res === TRUE) {
            echo 'ok';
            $zip->extractTo("testfolder2");
            $zip->close();
        } else {
            echo 'failed, code:' . $res;
        }
    }
    
    function Zip($source, $destination){
        if (!extension_loaded('zip') || !file_exists($source)){
            return false;
        }
        $zip = new ZipArchive();
        if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
            return false;
        }
        $source = str_replace('\\', '/', realpath($source));
        if (is_dir($source) === true){
    
            $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
            foreach ($files as $file){
                $file = str_replace('\\', '/', realpath($file));
                if (is_dir($file) === true){
                    $zip->addEmptyDir( str_replace($source . '/', '', $file . '/') );
                }else if (is_file($file) === true){
                    $zip->addFromString( str_replace($source . '/', '', $file), file_get_contents($file));
                }
            }
    
    
        }else if (is_file($source) === true){
            $zip->addFromString(basename($source), file_get_contents($source));
        }
        return $zip->close();
    }
    
    Zip( "testfolder/" , "./zipTest.zip" );
    unArchive();
    

代码适用于单个文件。 使用 ZipArchive 压缩文件后,我可以使用 WinRAR 手动解压缩,然后使用 WinRAR 重新压缩,然后 ZipArchive 可以成功解压缩该文件。 问题是 ZipArchive 不会提取它直接压缩的存档。 我还可以在 Notepad++ 中看到 ZipArchive zip 与 WinRAR zip 不同,文件大小也不同。我可以成功地将 winrar 作为 php 中的系统命令调用以获得所需的功能,但这似乎是个坏主意。 ZipArchive 创建无法提取的 zip 文件是否有某些原因?

错误消息:ZipArchive::extractTo(): [$zip->extractTo("testfolder2");] 行 [file] 中的参数无效

【问题讨论】:

  • 你有没有得到答案,我在 Windows 上遇到了同样的问题
  • testfolder2 文件夹是否已经存在?如果没有,那么您可能需要先创建一个 → if( ! file_exist('testfolder2')) {mkdir('testfolder2', 0777)}

标签: php zip unzip ziparchive


【解决方案1】:

RecursiveIteratorIterator 返回伪文件“.”而且,这在这里很重要,“..” - 父目录。当您使用 addEmptyDir 添加父目录时,ZipArchive 将添加它(不知何故)!您甚至可以尝试“$zip->addEmptyDir("../something")”,它不会抱怨。

现在,通常,zip 文件不会以这种方式运行。提取它们时,您希望所有内容都在您提取它们的文件夹中,而不是在父文件夹中。这就是为什么普通的 ZIP 提取程序不显示它的原因。

不过,PHP ZipArchive 甚至会提取这些文件夹。然后,这个错误会以某种方式发生,因为你试图包含“。”或“..”目录。

在 foreach 循环的开始添加这个来解决这个问题:

if (basename($file) === ".") { continue;}
if (basename($file) === "..") { continue; }

测试用例:

<?php
$archive = new ZipArchive();
$archive->open('c.zip',ZipArchive::CREATE);
$archive->addFile('a.txt');
$archive->addFile('b.txt');
$archive->addEmptyDir("../../down");
$archive->close();

$archive2 = new ZipArchive();
$archive2->open('c.zip');
$archive2->extractTo('here');
$archive2->close();

我只在 Windows 上测试过。

【讨论】:

    猜你喜欢
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    相关资源
    最近更新 更多