PHP5 には、階層データ構造の移動と処理に役立つ既製のインターフェイスのセットである Iterator が追加されています。これは、PHP5 の最も興味深い新機能の 1 つです。
これらのイテレータは、XML ドキュメント ツリーまたはファイルのコレクションの処理に必要なコードを大幅に削減します。 PHP5 では、ArrayIterator、CachingIterator、LimitIterator、RecursiveIterator、SimpleXMLIterator、DirectoryIterator など、多数のイテレータが使用されます。
DirectoryIterator は、ディレクトリ内のファイルを迅速かつ効率的に処理できます。コーディング プロセスにもう少し創造性を加えると、DirectoryIterator を使用して、ネストされたディレクトリ ツリーを再帰的に処理することもできます。どちらのタスクも、わずか数行のコードを使用して実行でき、「標準」アプローチに比べて大幅に改善されています。
単一レベルのディレクトリの処理 まず、単一レベルのディレクトリを処理するという単純なタスクから始めます。次のコード (リスト A) を入力 (またはコピー) し、ローカル構成を反映するようにディレクトリ パスを変更します。
リスト A
<?php$it = new DirectoryIterator("/tmp/mystuff");foreach($it as $file) {if ( !$it->isDot()) {echo $file . "n";}}?>このコードの出力をブラウザで表示すると、指定したディレクトリ内のファイルのリストが表示されます。どうしてこんなことになったのでしょうか? DirectoryIterator は、ディレクトリの内容を再記述するための所定のインターフェイスを提供します。ターゲット ディレクトリの場所がサンプリングされると、各要素がディレクトリ内のファイルを表す標準的な PHP 配列として扱うことができます。 isDot () メソッドを使用して「.」ディレクトリと「..」ディレクトリをそれぞれ除外することに注意してください。
ネストされたディレクトリ ツリーの処理 ネストされたディレクトリ ツリーを再帰的に処理することも、ほぼ同じくらい簡単です。この場合、DirectoryIterator は、単一レベルのディレクトリ内で見つかったすべてのオブジェクトをチェックして、それがファイルであるかディレクトリであるかを判断する必要があります。ディレクトリの場合は、1 つ下のレベルに移動して、次のレベルの内容を確認します。これは非常に複雑に聞こえるかもしれませんが、以前は通常 15 行を超えるコードが必要でした。
ただし、PHP5 では、上記の機能をすべて組み合わせた RecursiveIterator と RecursiveIteratorIterator という 2 つの新しいイテレーターのみが必要になります。リスト B を参照してください:
リスト B
<?php$it = new RecursiveDirectoryIterator("/tmp");foreach(new RecursiveIteratorIterator($it) as $file) {echo $file . "n";}?>このとき、次のように入力します。結果 開始ディレクトリの下にあるすべてのファイルとディレクトリがリストされます。言うまでもなく、この再帰的な組み込みインターフェイスは、特定のディレクトリ レベルにあるすべてのファイルを処理する必要がある場合に非常に便利です。たとえば、ディレクトリ ツリーを再帰的に圧縮したり、一連のネストされたファイルのグループ/所有者権限を変更したりする場合です。
実際のアプリケーション: ディレクトリ ツリーの印刷 グラフィカルなディレクトリ ツリーの印刷は、ディレクトリ再帰の一般的なアプリケーションです。 Iterator クラスのドキュメントには、このアプリケーション専用に作成されたインスタンス クラスが含まれているため、Iterator を使用してこのタスクを処理するのは非常に簡単です。 DirectoryTreeIterator (Marcus Boerger のおかげ) は、前述した RecursiveIteratorIterator にその他の改良点を提供します。特に、ツリー構造内の深さと位置を表す ASCII タグが挙げられます。
リスト C は、DirectoryTreeIterator の使用法を示しています。
リスト C
<?php$it = new DirectoryTreeIterator("/tmp/cookbook/");foreach($it as $path) {echo $path . "n";}?>次に、表示される出力の一部を示します
。 |-ch01| |-example01.php| |-example01.php|これらの DirectoryIterators の値をよりよく理解するには、標準のファイル関数とディレクトリ関数を使用して、このチュートリアルで説明されている 3 つのアプリケーションをコーディングしてみてください。