ZipArchive无法解压ZipArchive在PHP中拉链的文件

时间:2014-02-25 16:36:16

标签: php zip unzip ziparchive

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

  1. 使用包含文件的文件夹
  2. 使用ZipArchive
  3. 在PHP中压缩文件夹
  4. 使用ZipArchive
  5. 解压缩压缩文件夹
  6. 创建了新文件夹,但内部文件丢失

    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();
    
  7. 代码适用于单个文件。 使用ZipArchive压缩文件,我可以使用WinRAR手动解压缩,然后使用WinRAR重新压缩,然后ZipArchive可以成功解压缩该文件。 问题是ZipArchive不会提取它直接压缩的存档。 我还可以在Notepad ++中看到ZipArchive zip与WinRAR zip不同,文件大小也不同。我可以在php中成功调用winrar作为系统命令以获得所需的功能,但这似乎是一个坏主意。 ZipArchive是否创建了无法提取的zip文件?

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

1 个答案:

答案 0 :(得分:0)

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上测试过这个。