大家現在也許對但是遞歸函數是一個很復雜而且雜亂的東西,大多數開發者(包括我自己) 並不是真正喜歡使用它們。這就是為什麼當我的上一個項目需要為一個單獨文件掃描一個目錄層級時(一個典型的遞歸函數任務),我甚至沒有考慮過要循環自己的 代碼。我取而代之地直接使用了PEAR和它的File_Find類,免除了我搜索多層目錄結構的痛苦。
File_Find類是為了能讓你真 正做好兩件事情而設計的。第一,它可以讓你掃描一個目錄樹,然後將其轉換成為PHP結構——一個嵌套的數組——它反映了原始層級的父子關系。第二,它可以 讓你在一個目錄樹下搜索一個或多個類型相匹配的文件。這種類型可以是一個簡單的字符串,也可以是一個復雜的Perl規則的表達式;File_Find能夠 處理上述兩種中的任意一種格式,並將返回一個包括了每一對的詳細文件和路徑信息的數組。
一開始,手動安裝程序包,你可以下載它,然後將其內容提取到PEAR根目錄下,也可以利用PEAR安裝程序。
接下來,創建以下PHP腳本(列表A),並將它保存在你的Web服務器的文件根目錄下:
PHP類搜索定位目錄樹列表A
- < ?php
- // include class
- include(”Find.php”);
- // initialize finder
- $finder = new File_Find();
- // read directory tree and print
- $tree = $finder->mapTree(”/tmp”);
- print_r($tree);
- ?>
在此,我初始化了一個新的File_Find()對象, 並用一個目錄路徑調用其mapTree()方法。mapTree()方法讀取指定的目錄,然後產生它的一個兩元素的層級結構“數組表(array map)”。此數組中第一個元素列出了所找到的所有目標目錄下的子目錄,而第二個元素列出了找到的所有文件。然後就有可能掃描這些序列,在應用程序中使用 它們了——例如,重建目錄樹,或者在自定義標准的基礎上篩選文件和目錄。
列表B是以上腳本輸出的一個例子:
PHP類搜索定位目錄樹列表B
- Array
- (
- [0] => Array
- (
- [0] => /tmp
- [1] => /tmp/dummyA
- [2] => /tmp/dummyB
- [3] => /tmp/dummyA/dummyC
- )
- [1] => Array
- (
- [0] => /tmp/data.txt
- [1] => /tmp/dummyB/metoo.mp3
- [2] => /tmp/dummyB/track.dat
- [3] => /tmp/dummyA/dummyC/parrot.gif
- )
- )
你也可以用另一種方式,用mapTreeMultiple()方法,它遞歸讀取指定的目錄,產生一個復制其樹形結構的嵌套數組。列表C為你展示了一個例子。
PHP類搜索定位目錄樹列表C
- < ?php
- // include class
- include(”Find.php”);
- // initialize finder
- $finder = new File_Find();
- // print recursive directory tree
- $tree = $finder->mapTreeMultiple(”/tmp”);
- print_r($tree);
- ?>
列表D顯示了輸出結果:
PHP類搜索定位目錄樹列表D
- Array
- (
- [0] => data.txt
- [dummyA] => Array
- (
- [dummyC] => Array
- (
- [0] => parrot.gif
- )
- )
- [dummyB] => Array
- (
- [0] => metoo.mp3
- [1] => track.dat
- )
- )
提示:你可以給mapTreeMultiple()加上一個可選的參數,限定它在執行遞歸時向下查詢的層數。
用glob()方法,你可以在指定目錄下搜索與特定Perl兼容型的規則表達式匹配的文件。請看一下列表E。
PHP類搜索定位目錄樹列表E
- < ?php
- // include class
- include(”Find.php”);
- // initialize finder
- $finder = new File_Find();
- // search for matching files in named directory
- $results = $finder->glob(”/mp3/i”, “/usr/local/stuff”, “perl”);
- print_r($results);
- ?>
在這裡,glob()方法訪問指定目錄下所有名稱中帶有字符串mp3的文件。注意我對修飾符i的使用,它使得搜索沒有大小寫之分,還有我使用了第三個自變量,告訴類要使用Perl regex函數,而不是默認的PHP函數。
File_Find類由於它的search()方法而真正發揮作用起來,這個方法結合了mapTreeMultiple()和glob()方法的能力進行多層目錄搜索。列表F中是一個例子。
PHP類搜索定位目錄樹列表F
- < ?php
- // include class
- include(”Find.php”);
- // initialize finder
- $finder = new File_Find();
- // search for matching files
- // in named directory and subdirectories
- $results = $finder->search(”/exe/i”, “/usr/local/winstuff”, “perl”);
- print_r($results);
- ?>
列表G顯示了輸出的一個樣本:
PHP類搜索定位目錄樹列表G
- Array
- (
- [0] => /usr/local/winstuff/4HELP.EXE
- [1] => /usr/local/winstuff/ARJ.EXE
- [2] => /usr/local/winstuff/bzip2.exe
- [3] => /usr/local/winstuff/CRLF.EXE
- [4] => /usr/local/winstuff/DECODE.EXE
- [5] => /usr/local/winstuff/GREP.EXE
- [6] => /usr/local/winstuff/GPG/gpg.exe
- [7] => /usr/local/winstuff/GPG/uninst-gnupg.exe
- [8] => /usr/local/winstuff/GPG/WinPT.exe
- [9] => /usr/local/winstuff/Fprot/F-PROT.EXE
- )
這就是你的遞歸目錄查詢,僅僅只有四行代碼!
正如你所看到的那樣,File_Find使得簡單有效地完成一個相對復雜的任務成為可能,而且你會感到最小的壓力,這也就是我為什麼極力向你推薦它的原因。下次當你需要在PHP類搜索定位目錄樹上執行一個文件查找操作時,不妨你自己嘗試一下。祝你編程快樂!