首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 遞迴掃描目錄:列印所有檔案與子目錄結構

     編輯:PHP 相關知識

前言

在檔案管理、備份腳本或建立檔案索引時,常需遞迴遍歷指定目錄下的所有檔案與子目錄。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>";
?>

代碼解析

1. 路徑正規化

使用 rtrim($dir_path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR 確保路徑結尾恰好有一個分隔符,避免雙分隔符或缺少分隔符導致 is_dir() 判斷失敗。

2. 錯誤抑制與處理

@opendir() 抑制警告,若失敗輸出紅字提示並返回,不中斷整個遞迴流程。

3. 縮排顯示層級

str_repeat(' ', $level) 產生對應層級的空白,直觀呈現目錄樹結構。

4. 參考傳遞計數器

&$file_count 以參考方式傳遞,遞迴過程中累加,最終在最外層取得總數。

進階改良建議

  • 過濾隱藏檔:在迴圈開頭加入 if ($entry[0] === '.') continue; 跳過 .git、.env 等隱藏檔/目錄。
  • 限制最大深度:加入 $max_depth 參數,超過即返回,防止無限遞迴或效能問題。
  • 回傳結構化資料:改為回傳陣列/物件(含路徑、類型、大小、修改時間),供前端 JS 樹狀元件渲染,而非直接輸出 HTML。
  • 使用 SPL 迭代器:PHP 5.3+ 可用 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>";
}
?>

效能與安全提醒

  1. 大型目錄:遞迴掃描數萬檔案會消耗大量記憶體與 CPU,建議分批處理或使用隊列非同步執行。
  2. 權限控管:僅掃描應用程式有權限的目錄,避免洩露敏感路徑(如 /etc、C:\Windows)。
  3. 路徑注入:若掃描路徑來自用戶輸入,務必用 realpath() 解析並確認在允許根目錄下,防止目錄遍歷攻擊。

總結

遞迴掃描目錄是 PHP 檔案系統操作的基礎技能。掌握 opendir/readdir 底層 API 與 SPL 迭代器兩種寫法,並注意路徑正規化、錯誤處理、權限與效能,即能建立健壯的目錄遍歷功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved