dtx9931 2014-02-25 16:36
浏览 203

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

Trying to get import/export functionality.

  1. With a folder containing a file
  2. Zip the folder in PHP using ZipArchive
  3. Unzip the zipped folder using ZipArchive
  4. New folder is created, but the file inside is missing

    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();
    

Code works fine for single files. With a file zipped using ZipArchive, I can manually unzip using WinRAR, then rezip using WinRAR, and then ZipArchive can successfully unzip that file. The problem is that ZipArchive won't extract the archive that it directly zipped. I can also see in Notepad++ that the ZipArchive zip is different from the WinRAR zip, and the file size is different. I can successfully call winrar as a system command in php for the desired functionality, but this seems like a bad idea. Is there some reason ZipArchive creates zip files that it can't extract?

Error message: ZipArchive::extractTo(): Invalid argument in [file] on line [$zip->extractTo("testfolder2");]

  • 写回答

1条回答 默认 最新

  • dousi4472 2014-09-10 12:41
    关注

    The RecursiveIteratorIterator returns the pseudo-files "." and, that's important here, ".." - the parent directory. When you use addEmptyDir to add the parent directory, the ZipArchive will add it (somehow)! You may even try "$zip->addEmptyDir("../something")" and it will not complain.

    Now, usually, zip files don't behave this way. When you extract them, you expect all contents to be in the folder you extract them, not in the parent folders. This is why ordinary ZIP extraction programs do not show it.

    The PHP ZipArchive will extract even these folders, however. Then, this error will somehow occur, because you tried to include the "." or ".." directories.

    Add this at the beginning of the foreach cycle to resolve this:

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

    Test case:

    <?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();
    

    I tested this only on Windows.

    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器