在 PHP 開發中,遍歷目錄結構是常見的需求,例如建立檔案索引、批次處理檔案、生成網站地圖等。本文將介紹兩種經典且實用的目錄遍歷方法,分別基於 glob() 函數與 dir() 類,並提供完整的程式碼範例供參考。
glob() 函數能依據模式尋找檔案路徑,配合遞迴函數即可輕鬆實現深度優先遍歷。此方法程式碼簡潔,適合快速開發原型。
<?php
function myscandir($pathname) {
foreach (glob($pathname) as $filename) {
if (is_dir($filename)) {
// 遇到目錄則遞迴進入,注意路徑尾部加上 '/*'
myscandir($filename . '/*');
} else {
// 遇到檔案則輸出路徑
echo $filename . '<br/>';
}
}
}
// 範例:掃描 D:/wamp/www/exe1/ 目錄下所有檔案
myscandir('D:/wamp/www/exe1/*');
?>
關鍵點說明:
glob($pathname) 返回符合模式的檔案/目錄陣列。/*,否則無法匹配子目錄內容。dir() 類提供物件導向的目錄讀取介面,配合 read() 方法逐項讀取,邏輯更貼近底層操作,效能上略優於 glob(),且對特殊檔案名(如包含空格、中文)的相容性較好。
<?php
function myscandir($path) {
$mydir = dir($path);
while ($file = $mydir->read()) {
// 組合完整路徑
$p = $path . '/' . $file;
// 排除當前目錄 '.' 與上層目錄 '..'
if (($file != ".") && ($file != "..")) {
echo $p . '<br>';
}
// 若為目錄且非特殊目錄,則遞迴處理
if ((is_dir($p)) && ($file != ".") && ($file != "..")) {
myscandir($p);
}
}
$mydir->close(); // 良好習慣:關閉目錄句柄
}
// 範例:掃描當前檔案所在目錄的上兩層目錄
myscandir(dirname(dirname(__FILE__)));
?>
關鍵點說明:
dir($path) 返回一個 Directory 物件,擁有 read()、rewind()、close() 方法。. 與 ..,否則會陷入無限遞迴。$mydir->close() 釋放資源。| 比較項目 | glob() 遞迴 | dir() 類迴圈 |
|---|---|---|
| 程式碼簡潔度 | 高 | 中 |
| 執行效能 | 較低(大量檔案時明顯) | 較高 |
| 特殊檔名支援 | 一般 | 良好 |
| 適用場景 | 快速原型、小型專案 | 正式專案、大量檔案、長期維護 |
PHP 5.3+ 內建 RecursiveDirectoryIterator 與 RecursiveIteratorIterator,提供更強大、更符合現代開發習慣的遍歷方式:
<?php
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('/path/to/dir', FilesystemIterator::SKIP_DOTS)
);
foreach ($iterator as $fileInfo) {
echo $fileInfo->getPathname() . '<br/>';
}
?>
優點包括:自動處理遞迴、可靈活過濾(如 RegexIterator)、記憶體效率高(逐項產生)、支援鏈式操作。建議新專案優先採用 SPL 迭代器。
本文介紹了兩種傳統的 PHP 目錄遍歷方法:glob() 遞迴與 dir() 類迴圈,並對比了其優缺點。實務上,視專案規模與 PHP 版本選擇合適方案;若環境允許,強烈推薦使用 SPL 迭代器以獲得更優雅、高效且可維護的程式碼。