4

これはほとんどの人にとってばかげた質問かもしれませんが、私は次のフォルダを持っています。これを圧縮したいと思います。

FolderI
   Folder1
   Folder2
   Folder3
   ..
   ..
   FolderN

さて、特にここでは、オンラインのリソースが非常に多いため、に圧縮FolderIするのは非常に簡単です。しかし、ファイルを解凍すると、を作成するのではなく、現在のディレクトリに直接データを入力するように、を含むzipFile.zipを作成したいと思います。zipFile.zipFolder1...FolderNFolder1...FolderNFolderIFolder1...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スクリプトを使用してcompress / archiveフォルダーから取得され、変更しようとしました。しかし、動作しませんでした-FolderIはまだ圧縮されています。しかし、解凍するとmy-archive.zip、が表示されFolderI、そのFolder1..FolderN中に表示されます。@Alixのコードもここのどこかで見ましたが、これは同じことをしました。しかし、あまりフォローしていませんでした。

どんな種類の助けも素晴らしいでしょう。コードでない場合は、少なくとも私を正しい方向に向けてください。

ありがとう

****ここの誰かがこれを行う方法を知っていますか?****

@Mods and Admins:ソリューションが単純すぎるか、PHPがこれをまったく実行できないのですか?

4

2 に答える 2

2

ここで発生している問題は、イテレータ内のが(デフォルトでフラグが使用されているため)$keyフルパスであり、RecursiveDirectoryIteratorコンストラクタで指定された相対部分が含まれていることです。RecursiveDirectoryIterator::KEY_AS_PATHNAME

したがって、たとえば、次の階層があります。

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()、両方とも同じ仕事をします。

于 2013-03-15T19:56:24.473 に答える
1

道順に関しては、私はこれを提供することができます:

これは、私には少し複雑に見えますが、foreachループを追加して、次のようなイテレータを作成することで積み重ねることができます。

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

Globはおそらくあなたのためにもっと多くのことをすることができ、おそらくそれらのイテレータオブジェクトを排除して、glob出力を反復するだけにすることができます。

于 2013-03-14T22:14:33.257 に答える