ZipArchive не может разархивировать файлы, которые ZipArchive архивирует в PHP
Попытка получить функциональность импорта / экспорта.
- С папкой, содержащей файл
- Сжать папку в PHP с помощью ZipArchive
- Распакуйте zip-папку, используя ZipArchive
Новая папка создана, но файл внутри отсутствует
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(): неверный аргумент в [file] в строке [$zip->extractTo("testfolder2");]
1 ответ
RecursiveIteratorIterator возвращает псевдофайлы "." и, что здесь важно, ".." - родительский каталог. Когда вы используете addEmptyDir для добавления родительского каталога, ZipArchive добавит его (как угодно)! Вы можете даже попробовать "$zip->addEmptyDir("../ что-то ")", и он не будет жаловаться.
Теперь, как правило, почтовые файлы ведут себя не так. Когда вы извлекаете их, вы ожидаете, что все содержимое будет в папке, в которую вы их извлекаете, а не в родительских папках. Вот почему обычные программы извлечения 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.