在压缩文件中没有父文件夹的文件夹中压缩文件

时间:2013-03-14 21:34:08

标签: php zip

这对大多数人来说可能是一个愚蠢的问题,但我有以下文件夹,我想压缩。

FolderI
   Folder1
   Folder2
   Folder3
   ..
   ..
   FolderN

现在,将FolderI压缩到zipFile.zip非常简单,因为有很多在线资源,特别是在这里!但是,我想创建包含zipFile.zip的{​​{1}},这样当解压缩文件时,它会直接使用Folder1...FolderN填充当前目录,而不是创建Folder1...FolderN,其中有FolderI

我一直在尝试的一些事情是:

Folder1...FolderN

这是从compress/archive folder using php script获取的,我试图改变它。虽然没有工作 - FolderI仍然是压缩的。但是,当我解压缩$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(); 时,我会在其中获得my-archive.zip然后FolderI 。我也在这里看到了来自@Alix的代码,它做了同样的事情。但是,并没有真正效仿。

任何形式的帮助都会很棒。如果不是代码,至少指向正确的方向。

由于

****这里有人知道怎么做吗? ****

@Mods和Admins:解决方案是否过于简单,或者PHP根本无法做到这一点?

2 个答案:

答案 0 :(得分:2)

这里出现的问题是迭代器中的$key是完整路径(因为默认使用RecursiveDirectoryIterator::KEY_AS_PATHNAME标志),其中包括RecursiveDirectoryIterator构造函数中指定的相对部分。

例如,我们有以下层次结构:

folderI
├─ folder1
│  ├─ item.php
│  └─ so.php
└─ folder2
   └─ item.html

使用new RecursiveDirectoryIterator("folderI")创建的迭代器。

当您回复$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将对未知方法的任何调用传递给“内部迭代器”,在本例中是RecursiveDirectoryIterator。同样,你可以做$iterator->getInnerIterator()->getSubPathname(),两者都做同样的工作。

答案 1 :(得分:1)

就方向而言,我可以提供:

这看起来有点过于复杂,但你可以通过添加一个foreach循环来创建那些迭代器,如下所示:

foreach (glob('./*', GLOB_ONLYDIR) as $dir_name) {
   // iterator
   // add file
}

Glob可能会为你做更多的事情,可能会消除那些迭代器对象,而只是迭代遍历glob输出。