简体   繁体   English

ZipArchive无法解压缩ZipArchive在PHP中压缩的文件

[英]ZipArchive can't unzip files that ZipArchive zips in PHP

Trying to get import/export functionality. 尝试获取导入/导出功能。

  1. With a folder containing a file 使用包含文件的文件夹
  2. Zip the folder in PHP using ZipArchive 使用ZipArchive在PHP中压缩文件夹
  3. Unzip the zipped folder using ZipArchive 使用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. 使用ZipArchive压缩文件后,我可以使用WinRAR手动解压缩,然后使用WinRAR重新压缩,然后ZipArchive可以成功解压缩该文件。 The problem is that ZipArchive won't extract the archive that it directly zipped. 问题在于ZipArchive不会提取直接压缩的存档。 I can also see in Notepad++ that the ZipArchive zip is different from the WinRAR zip, and the file size is different. 我还可以在Notepad ++中看到ZipArchive zip与WinRAR zip不同,并且文件大小也不同。 I can successfully call winrar as a system command in php for the desired functionality, but this seems like a bad idea. 我可以成功调用winrar作为php中的系统命令以获得所需的功能,但这似乎是个坏主意。 Is there some reason ZipArchive creates zip files that it can't extract? ZipArchive是否有某些原因创建无法提取的zip文件?

Error message: ZipArchive::extractTo(): Invalid argument in [file] on line [$zip->extractTo("testfolder2");] 错误消息:ZipArchive :: extractTo():[$ zip-> extractTo(“ testfolder2”);]行上[file]中的无效参数

The RecursiveIteratorIterator returns the pseudo-files "." RecursiveIteratorIterator返回伪文件“”。 and, that's important here, ".." - the parent directory. 并且,这里很重要,“ ..”-父目录。 When you use addEmptyDir to add the parent directory, the ZipArchive will add it (somehow)! 当您使用addEmptyDir添加父目录时,ZipArchive将添加它(以某种方式)! You may even try "$zip->addEmptyDir("../something")" and it will not complain. 您甚至可以尝试“ $ zip-> addEmptyDir(“ ../ something”)”,它不会出现问题。

Now, usually, zip files don't behave this way. 现在,通常,zip文件不会采用这种方式。 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. 这就是为什么普通的ZIP提取程序不显示它的原因。

The PHP ZipArchive will extract even these folders, however. 但是,PHP ZipArchive甚至会提取这些文件夹。 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: 在foreach周期开始时添加此代码可解决此问题:

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. 我仅在Windows上对此进行了测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM