在 PHP 開發中,遍歷目錄結構是常見需求。本文提供三種成熟方案,涵蓋從 PHP 4 相容的傳統寫法到現代 scandir() 與 glob() 的高效實作,並附上跨平台建議。
opendir() + readdir() 遞迴(PHP 4+ 相容)此寫法不依賴新函式,適合舊版環境或教學示範遞迴邏輯:
<?php
/**
* 遞迴掃描目錄,回傳多維陣列
* @param string $dir 目標路徑
* @return array 結構:檔案為索引陣列,目錄為關聯陣列(鍵名=目錄名,值=遞迴結果)
*/
function my_scandir($dir) {
$files = [];
if ($handle = opendir($dir)) {
while (($file = readdir($handle)) !== false) {
if ($file !== '..' && $file !== '.') {
$path = $dir . '/' . $file;
if (is_dir($path)) {
$files[$file] = my_scandir($path); // 遞迴
} else {
$files[] = $file;
}
}
}
closedir($handle);
}
return $files;
}
?>
scandir() 簡化迴圈(PHP 5+ 推薦)scandir() 直接回傳陣列,程式碼更精簡:
<?php
function my_scandir1($dir) {
$files = [];
$list = scandir($dir);
foreach ($list as $file) {
if ($file !== '..' && $file !== '.') {
$path = $dir . '/' . $file;
if (is_dir($path)) {
$files[$file] = my_scandir1($path);
} else {
$files[] = $file;
}
}
}
return $files;
}
?>
glob() 直觀列印(適合快速除錯)利用 glob() 模式比對,配合 DIRECTORY_SEPARATOR 與 PHP_EOL 達成跨平台:
<?php
function fetchDir($dir) {
foreach (glob($dir . DIRECTORY_SEPARATOR . '*') as $file) {
echo $file . PHP_EOL;
if (is_dir($file)) {
fetchDir($file); // 遞迴
}
}
}
// 使用範例(Windows 路徑)
fetchDir('D:' . DIRECTORY_SEPARATOR . 'wamp' . DIRECTORY_SEPARATOR . 'www' . DIRECTORY_SEPARATOR . 'any');
?>
DIRECTORY_SEPARATOR 代替硬編碼 / 或 \。PHP_EOL 取代 \n。scandir() 一次讀入記憶體;glob() 同樣;若目錄極大,建議改用 DirectoryIterator (SPL) 逐個迭代,降低記憶體壓力。is_readable() 判斷,避免因權限不足導致警告或中斷。若需產生檔案樹狀結構給前端(如 JSON 輸出),可將上述函式回傳的多維陣列直接 json_encode();若需計算總大小、過濾副檔名,只需在遞迴處加入判斷邏輯即可。