Закрепление файлов в папке без родительской папки в зашифрованном файле

Это может быть глупый вопрос для большинства, но у меня есть следующая папка, которую я хочу заархивировать.

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.