Это может быть глупый вопрос для большинства, но у меня есть следующая папка, которую я хочу заархивировать.
FolderI Folder1 Folder2 Folder3 .. .. FolderN
Теперь, FolderI в zipFile.zip , довольно легко из-за большого количества ресурсов в Интернете, особенно здесь! Но я хочу создать zipFile.zip , содержащий Folder1...FolderN , так что когда файл распакуется, он будет напрямую заполнять текущий каталог Folder1...FolderN , вместо создания FolderI , у которого есть Folder1...FolderN в нем.
Некоторые из вещей, которые я пытался:
$zip = new ZipArchive(); // open archive if ($zip->open('my-archive.zip', ZIPARCHIVE::CREATE) !== TRUE) { die ("Could not open archive"); } // initialize an iterator // pass it the directory to be processed $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("FolderI/")); // iterate over the directory // add each file found to the archive foreach ($iterator as $key=>$value) { $zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key"); } // close and save archive $zip->close();
Это было взято из папки сжатия / архива с использованием php-скрипта, и я попытался изменить его. Не работает, но FolderI все еще застегнут. Но, когда я разархивирую my-archive.zip , я получаю FolderI а затем Folder1..FolderN внутри него . Я также видел здесь код от @Alix, который сделал то же самое. Но, на самом деле, не следовало многого.
Любая помощь будет отличной. Если не код, по крайней мере, указать мне в правильном направлении.
благодаря
**** Кто-нибудь знает, как это сделать? ****
@Mods and Admins: Является ли решение слишком простым или PHP не может этого сделать вообще?
Проблема, которая здесь возникает, заключается в том, что $key в итераторе является полным путем (поскольку по умолчанию используется флаг RecursiveDirectoryIterator::KEY_AS_PATHNAME ), который включает относительную часть, указанную в конструкторе RecursiveDirectoryIterator.
Так, например, у нас есть следующая иерархия:
folderI ├─ folder1 │ ├─ item.php │ └─ so.php └─ folder2 └─ item.html
Итератор, созданный с помощью new RecursiveDirectoryIterator("folderI") .
Когда вы item.php $key вы получите следующее для item.php
folderI/folder1/item.php
Аналогично, если бы мы сделали new RecursiveDirectoryIterator("../somewhere/folderI") , тогда $key будет выглядеть так:
../somewhere/folderI/folder1/item.php
Вы хотите получить путь к файлу, не включая путь, используемый для создания итератора. К счастью, у RecursiveDirectoryIterator есть метод, единственной целью которого является выполнение именно этого.
RecursiveDirectoryIterator :: getSubPathname ()
Вы можете использовать следующее, что будет проще
$newKey = $iterator->getSubPathname();
Это вернет следующее для item.php , учитывая ту же структуру папок, которая показана выше:
folder1/item.php
Метод можно использовать так:
foreach ($iterator as $key=>$value) { $zip->addFile(realpath($key), $iterator->getSubPathname()) or die ("ERROR: Could not add file: $key"); }
Кроме того, мы можем использовать $iterator->getSubPathname() здесь, потому что RecursiveIteratorIterator передает любые вызовы неизвестным методам «внутреннему итератору», который в этом случае является рекурсивнымDirectoryIterator. Точно так же вы можете сделать $iterator->getInnerIterator()->getSubPathname() , оба выполняют ту же работу.
Что касается направлений, я могу предложить следующее:
Это выглядит немного сложнее для меня, как есть, но вы можете нагромождать, добавив цикл foreach для создания таких итераторов:
foreach (glob('./*', GLOB_ONLYDIR) as $dir_name) { // iterator // add file }
Glob, вероятно, может сделать намного больше для вас, возможно, устранит те итерационные объекты в пользу простое повторение вывода glob.