今はそうかもしれませんしかし、再帰関数は非常に複雑で厄介なもので、ほとんどの開発者 (私を含む) はあまり使いたがりません。そのため、私の最後のプロジェクトで単一のファイルのディレクトリ階層をスキャンする必要があったとき (典型的な再帰関数タスク)、私は独自のコードをループすることさえ考えませんでした。代わりに、PEAR とその File_Find クラスを直接使用して、複数レベルのディレクトリ構造を検索する手間を省きました。
File_Find クラスは、実際に 2 つのことを実行できるように設計されています。まず、ディレクトリ ツリーをスキャンして、元の階層の親子関係を反映する PHP 構造 (ネストされた配列) に変換できます。 2 番目に、ディレクトリ ツリー内で一致するタイプの 1 つ以上のファイルを検索できます。このタイプは単純な文字列または複雑な Perl ルール式にすることができ、File_Find は上記の形式のいずれかを処理でき、各ペアの詳細なファイルとパスを返します。
まず、パッケージを手動でインストールします。ダウンロードしてその内容を PEAR ルート ディレクトリに抽出することも、PEAR インストーラーを利用することもできます。
次に、次の PHP スクリプト (リスト A) を作成し、Web サーバーのファイル ルートに保存します。
PHP Class Search Locate Directory Tree Listing A
<ol class="dp-xml"> <li class="alt"><span><span class="tag"><</span><span> ?php </span></span></li><li><span>// include class </span></li><li class="alt"><span>include(”Find.php”); </span></li><li><span>// initialize finder </span></li><li class="alt"><span>$</span><span class="attribute">finder</span><span> = </span><span class="attribute-value">new</span><span> File_Find(); </span></li><li><span>// read directory tree and print </span></li><li class="alt"><span>$</span><span class="attribute">tree</span><span> = $finder-</span><span class="tag">></span><span>mapTree(”/tmp”); </span></span></li> <li><span>print_r($tree); </span></li> <li class="alt"> <span class="tag">?></span><span> </span> </li> </ol>
ここで、新しい File_Find()オブジェクトが初期化され、その mapTree() メソッドがディレクトリ パスを指定して呼び出されます。 mapTree() メソッドは、指定されたディレクトリを読み取り、そのディレクトリの 2 要素の階層「配列マップ」を生成します。この配列の最初の要素はターゲット ディレクトリの下にあるすべてのサブディレクトリをリストし、2 番目の要素は見つかったすべてのファイルをリストします。これらのシーケンスをスキャンしてアプリケーションで使用することが可能になります。たとえば、ディレクトリ ツリーを再構築したり、カスタム基準に基づいてファイルやディレクトリをフィルタリングしたりすることができます。
リスト B は、上記のスクリプトの出力の例です。
PHP クラス検索場所ディレクトリ ツリー リスト B
<ol class="dp-xml"> <li class="alt"><span><span>Array </span></span></li> <li><span>( </span></li> <li class="alt"> <span>[0] =</span><span class="tag">></span><span> Array </span> </li> <li><span>( </span></li> <li class="alt"> <span>[0] =</span><span class="tag">></span><span> /tmp </span> </li> <li> <span>[1] =</span><span class="tag">></span><span> /tmp/dummyA </span> </li> <li class="alt"> <span>[2] =</span><span class="tag">></span><span> /tmp/dummyB </span> </li> <li> <span>[3] =</span><span class="tag">></span><span> /tmp/dummyA/dummyC </span> </li> <li class="alt"><span>) </span></li> <li> <span>[1] =</span><span class="tag">></span><span> Array </span> </li> <li class="alt"><span>( </span></li> <li> <span>[0] =</span><span class="tag">></span><span> /tmp/data.txt </span> </li> <li class="alt"> <span>[1] =</span><span class="tag">></span><span> /tmp/dummyB/metoo.mp3 </span> </li> <li> <span>[2] =</span><span class="tag">></span><span> /tmp/dummyB/track.dat </span> </li> <li class="alt"> <span>[3] =</span><span class="tag">></span><span> /tmp/dummyA/dummyC/parrot.gif </span> </li> <li><span>) </span></li> <li class="alt"><span>) </span></li> </ol>
また、mapTreeMultiple() メソッドを使用して、別の方法を使用することもできます。指定されたディレクトリで、そのツリー構造をコピーするネストされた配列を生成します。リスト C に例を示します。
PHP クラス検索場所ディレクトリ ツリー リスト C
<ol class="dp-xml"> <li class="alt"><span><span class="tag"><</span><span> ?php </span></span></li><li><span>// include class </span></li><li class="alt"><span>include(”Find.php”); </span></li><li><span>// initialize finder </span></li><li class="alt"><span>$</span><span class="attribute">finder</span><span> = </span><span class="attribute-value">new</span><span> File_Find(); </span></li><li><span>// print recursive directory tree </span></li><li class="alt"><span>$</span><span class="attribute">tree</span><span> = $finder-</span><span class="tag">></span><span>mapTreeMultiple(”/tmp”); </span></span></li> <li><span>print_r($tree); </span></li> <li class="alt"> <span class="tag">?></span><span> </span> </li> </ol>
リスト D は出力結果を示します:
PHP クラス検索場所ディレクトリ ツリー リスト D
<ol class="dp-xml"> <li class="alt"><span><span>Array </span></span></li> <li><span>( </span></li> <li class="alt"> <span>[0] =</span><span class="tag">></span><span> data.txt </span> </li> <li> <span>[dummyA] =</span><span class="tag">></span><span> Array </span> </li> <li class="alt"><span>( </span></li> <li> <span>[dummyC] =</span><span class="tag">></span><span> Array </span> </li> <li class="alt"><span>( </span></li> <li> <span>[0] =</span><span class="tag">></span><span> parrot.gif </span> </li> <li class="alt"><span>) </span></li> <li><span>) </span></li> <li class="alt"> <span>[dummyB] =</span><span class="tag">></span><span> Array </span> </li> <li><span>( </span></li> <li class="alt"> <span>[0] =</span><span class="tag">></span><span> metoo.mp3 </span> </li> <li> <span>[1] =</span><span class="tag">></span><span> track.dat </span> </li> <li class="alt"><span>) </span></li> <li><span>) </span></li> </ol>
ヒント: mapTreeMultiple() を追加できます。最後のオプションのパラメータは、再帰の実行時に検索するレベルの数を制限します。
glob() メソッドを使用すると、指定したディレクトリ内で特定の Perl 互換の正規表現に一致するファイルを検索できます。リスト E をご覧ください。
PHP クラスの検索場所ディレクトリ ツリー リスト E
<ol class="dp-xml"> <li class="alt"><span><span class="tag"><</span><span> ?php </span></span></li><li><span>// include class </span></li><li class="alt"><span>include(”Find.php”); </span></li><li><span>// initialize finder </span></li><li class="alt"><span>$</span><span class="attribute">finder</span><span> = </span><span class="attribute-value">new</span><span> File_Find(); </span></li><li><span>// search for matching files in named directory </span></li><li class="alt"><span>$</span><span class="attribute">results</span><span> = $finder-</span><span class="tag">></span><span>glob(”/mp3/i”, “/usr/local/stuff”, “perl”); </span></span></li> <li><span>print_r($results); </span></li> <li class="alt"> <span class="tag">?></span><span> </span> </li> </ol>
ここで、glob() メソッドは、指定されたディレクトリ内の名前に文字列 mp3 が含まれるすべてのファイルにアクセスします。検索で大文字と小文字を区別しないようにする i 修飾子の使用と、デフォルトの PHP 関数の代わりに Perl 正規表現関数を使用するようにクラスに指示する 3 番目の引数の使用に注目してください。
File_Find クラスは、マルチレベルのディレクトリ検索用に、mapTreeMultiple() メソッドと glob() メソッドの機能を組み合わせた search() メソッドのおかげで真価を発揮します。リスト F は一例です。
PHP クラス検索によりディレクトリ ツリー リスト F が特定されます
<ol class="dp-xml"> <li class="alt"><span><span class="tag"><</span><span> ?php </span></span></li><li><span>// include class </span></li><li class="alt"><span>include(”Find.php”); </span></li><li><span>// initialize finder </span></li><li class="alt"><span>$</span><span class="attribute">finder</span><span> = </span><span class="attribute-value">new</span><span> File_Find(); </span></li><li><span>// search for matching files </span></li><li class="alt"><span>// in named directory and subdirectories </span></li><li><span>$</span><span class="attribute">results</span><span> = $finder-</span><span class="tag">></span><span>search(”/exe/i”, “/usr/local/winstuff”, “perl”); </span></span></li> <li class="alt"><span>print_r($results); </span></li> <li> <span class="tag">?></span><span> </span> </li> </ol>
リスト G は出力のサンプルを示しています。
PHP クラス検索によりディレクトリ ツリー リスト G
<ol class="dp-xml"> <li class="alt"><span><span>Array </span></span></li> <li><span>( </span></li> <li class="alt"> <span>[0] =</span><span class="tag">></span><span> /usr/local/winstuff/4HELP.EXE </span> </li> <li> <span>[1] =</span><span class="tag">></span><span> /usr/local/winstuff/ARJ.EXE </span> </li> <li class="alt"> <span>[2] =</span><span class="tag">></span><span> /usr/local/winstuff/bzip2.exe </span> </li> <li> <span>[3] =</span><span class="tag">></span><span> /usr/local/winstuff/CRLF.EXE </span> </li> <li class="alt"> <span>[4] =</span><span class="tag">></span><span> /usr/local/winstuff/DECODE.EXE </span> </li> <li> <span>[5] =</span><span class="tag">></span><span> /usr/local/winstuff/GREP.EXE </span> </li> <li class="alt"> <span>[6] =</span><span class="tag">></span><span> /usr/local/winstuff/GPG/gpg.exe </span> </li> <li> <span>[7] =</span><span class="tag">></span><span> /usr/local/winstuff/GPG/uninst-gnupg.exe </span> </li> <li class="alt"> <span>[8] =</span><span class="tag">></span><span> /usr/local/winstuff/GPG/WinPT.exe </span> </li> <li> <span>[9] =</span><span class="tag">></span><span> /usr/local/winstuff/Fprot/F-PROT.EXE </span> </li> <li class="alt"><span>) </span></li> </ol>
これは再帰的なディレクトリ クエリのみです。コードは4行です!
ご覧のとおり、File_Find を使用すると、比較的複雑なタスクを簡単かつ効率的に完了でき、ストレスも最小限に抑えられるため、強くお勧めします。次回、PHP クラス検索場所ディレクトリ ツリーでファイル検索操作を実行する必要がある場合は、自分で試してみるとよいでしょう。楽しいプログラミングを!