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

PHP 遞迴掃描目錄完整實作:取得所有檔案與子目錄結構陣列

     編輯:PHP 綜合知識

專案常需掃描特定目錄下的所有檔案與子目錄(如建立檔案索引、批次處理、產生網站地圖)。本文提供一個健全的遞迴函式 read_all_dir(),回傳結構化陣列,並處理邊界條件與資源釋放。

完整函式程式碼

<?php
/**
 * 遞迴讀取目錄結構
 * @param string $dir  絕對或相對路徑
 * @return array       結構:['dir' => [路徑 => 子結構], 'file' => [檔案路徑...]]
 */
function read_all_dir(string $dir): array
{
    $result = ['dir' => [], 'file' => []];

    // 確保路徑存在且可讀
    if (!is_dir($dir) || !is_readable($dir)) {
        return $result;
    }

    $handle = opendir($dir);
    if ($handle === false) {
        return $result;
    }

    while (($file = readdir($handle)) !== false) {
        // 跳過 . 與 ..
        if ($file === '.' || $file === '..') {
            continue;
        }

        $cur_path = $dir . DIRECTORY_SEPARATOR . $file;

        if (is_dir($cur_path)) {
            // 遞迴處理子目錄
            $result['dir'][$cur_path] = read_all_dir($cur_path);
        } else {
            // 收集檔案
            $result['file'][] = $cur_path;
        }
    }

    closedir($handle);
    return $result;
}

// 使用範例
$tree = read_all_dir(__DIR__ . '/storage');
echo '<pre>';
print_r($tree);
echo '</pre>';

回傳結構範例

Array
(
    [dir] => Array
        (
            [/var/www/storage/images] => Array
                (
                    [dir] => Array()
                    [file] => Array
                        (
                            [0] => /var/www/storage/images/photo.jpg
                            [1] => /var/www/storage/images/logo.png
                        )
                )
        )
    [file] => Array
        (
            [0] => /var/www/storage/readme.txt
            [1] => /var/www/storage/config.ini
        )
)

進階擴充建議

  • 過濾副檔名:在 else 區塊加入 pathinfo($cur_path, PATHINFO_EXTENSION) 判斷。
  • 限制遞迴深度:增加參數 $depth = 0, $maxDepth = 10,避免過深導致堆疊溢位。
  • 使用 SPL 迭代器:現代 PHP(5.3+)可直接用 RecursiveDirectoryIterator + RecursiveIteratorIterator,程式碼更簡潔:
$iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS)
);
foreach ($iterator as $fileInfo) {
    if ($fileInfo->isFile()) {
        echo $fileInfo->getPathname() . PHP_EOL;
    }
}

效能與權限提醒

  • 大量檔案(>10 萬)時,遞迴函式可能耗盡記憶體,建議改用 Generator(yield)逐筆產出。
  • 確保 PHP 執行使用者對目標目錄有 r+x 權限,否則 opendir() 會失敗回傳 false。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved