在檔案管理、備份腳本或建立檔案索引時,常需遞迴遍歷指定目錄下的所有檔案與子目錄。PHP 提供 opendir()、readdir()、is_dir() 等底層函數,結合遞迴函數即可實現完整的目錄樹走訪。本文提供一個可直接使用、支援縮排顯示層級的實用範例。
<?php
/**
* 遞迴掃描並輸出目錄結構
*
* @param string $dir_path 要掃描的目錄路徑(結尾需含分隔符)
* @param int $level 當前遞迴層級(內部使用,預設 0)
* @param int &$file_count 檔案總數參考(可選)
*/
function scan_dir(string $dir_path, int $level = 0, int &$file_count = 0): void {
// 正規化路徑分隔符
$dir_path = rtrim($dir_path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$handle = @opendir($dir_path);
if ($handle === false) {
echo str_repeat(' ', $level) . "<span style='color:red'>無法開啟目錄: {$dir_path}</span><br>";
return;
}
while (($entry = readdir($handle)) !== false) {
// 跳過 . 和 ..
if ($entry === '.' || $entry === '..') continue;
$full_path = $dir_path . $entry;
$is_dir = is_dir($full_path);
// 輸出縮排與連結
echo str_repeat(' ', $level);
if ($is_dir) {
echo "<strong><a href='{$full_path}' target='_blank'>📁 {$entry}</a></strong><br>";
$file_count++; // 目錄也計入計數(可依需求調整)
scan_dir($full_path, $level + 1, $file_count);
} else {
echo "<a href='{$full_path}' target='_blank'>📄 {$entry}</a><br>";
$file_count++;
}
}
closedir($handle);
}
// 使用範例
$root = 'D:/wamp/www/test/lamp61'; // 請修改為實際存在的路徑
$total = 0;
echo "<h3>目錄掃描結果:{$root}</h3>";
scan_dir($root, 0, $total);
echo "<hr><strong>檔案/目錄總數:{$total}</strong>";
?>
使用 rtrim($dir_path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR 確保路徑結尾恰好有一個分隔符,避免雙分隔符或缺少分隔符導致 is_dir() 判斷失敗。
@opendir() 抑制警告,若失敗輸出紅字提示並返回,不中斷整個遞迴流程。
str_repeat(' ', $level) 產生對應層級的空白,直觀呈現目錄樹結構。
&$file_count 以參考方式傳遞,遞迴過程中累加,最終在最外層取得總數。
if ($entry[0] === '.') continue; 跳過 .git、.env 等隱藏檔/目錄。$max_depth 參數,超過即返回,防止無限遞迴或效能問題。RecursiveDirectoryIterator + RecursiveIteratorIterator 簡化代碼:<?php
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $path => $info) {
$level = $iterator->getDepth();
echo str_repeat(' ', $level);
echo $info->isDir() ? "<strong>📁 {$info->getFilename()}</strong>" : "📄 {$info->getFilename()}";
echo "<br>";
}
?>
/etc、C:\Windows)。realpath() 解析並確認在允許根目錄下,防止目錄遍歷攻擊。遞迴掃描目錄是 PHP 檔案系統操作的基礎技能。掌握 opendir/readdir 底層 API 與 SPL 迭代器兩種寫法,並注意路徑正規化、錯誤處理、權限與效能,即能建立健壯的目錄遍歷功能。