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

PHP 遞迴取得資料夾所有檔案的簡易演算法實作

     編輯:PHP 綜合知識

快速撰寫一個「掃描資料夾回傳所有檔案路徑」的函數,常見於臨時腳本、部署工具、日誌清理。本文提供最精簡的遞迴寫法,並說明為何生產環境建議改用 SPL 迭代器。

極簡遞迴版(約 15 行)

function my_scandir($dir)
{
    $files = [];
    if (!is_dir($dir)) return $files;

    $handle = opendir($dir);
    if (!$handle) return $files;

    while (($file = readdir($handle)) !== false) {
        if ($file === '.' || $file === '..') continue;

        $path = $dir . DIRECTORY_SEPARATOR . $file;
        if (is_dir($path)) {
            $files[$file] = my_scandir($path); // 子目錄以目錄名為鍵,值為遞迴結果
        } else {
            $files[] = $path; // 檔案直接存完整路徑
        }
    }
    closedir($handle);
    return $files;
}

輸出結構範例

$tree = my_scandir(__DIR__ . '/storage');
/*
Array
(
    [0] => /var/www/storage/readme.txt
    [logs] => Array
        (
            [0] => /var/www/storage/logs/2024-01-01.log
            [0] => /var/www/storage/logs/2024-01-02.log
        )
    [images] => Array
        (
            [0] => /var/www/storage/images/photo.jpg
        )
)
*/

關鍵細節

  • opendir/readdir/closedir:底層目錄流操作,比 scandir() 記憶體效率略好(逐個讀取)。
  • DIRECTORY_SEPARATOR:跨平台相容(Windows \、Linux /)。
  • 回傳結構:**混合陣列**——數字索引存檔案路徑,關聯索引存子目錄樹。前端遞迴渲染樹狀圖時需同時判斷 is_int($key)。
  • 未做副檔名過濾、大小排序、權限錯誤處理,屬**教學/臨時用途**。

生產環境建議:改用 SPL 迭代器

function scan_dir_spl($dir, $filter = [])
{
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::SELF_FIRST
    );

    $result = [];
    foreach ($iterator as $path => $info) {
        if ($info->isDir()) {
            $result[$info->getFilename()] = []; // 佔位,實際樹狀需額外建構
        } elseif (empty($filter) || in_array(strtolower($info->getExtension()), $filter)) {
            $result[] = $path;
        }
    }
    return $result;
}

為何 SPL 更好?

指標遞迴函數SPL 迭代器
記憶體峰值高(遞迴堆疊 + 完整陣列)低(生成器逐個產出)
最大深度限制受限於 PHP 堆疊(~幾千層)無實質限制
錯誤處理需自行 try-catch可掛 set_exception_handler
可中斷/暫停困難容易(生成器特性)

一鍵扁平化輸出(適用兩種版本)

function flatten($tree)
{
    $flat = [];
    array_walk_recursive($tree, function($v) use (&$flat) { $flat[] = $v; });
    return $flat;
}

$allFiles = flatten(my_scandir('/data'));
// 直接得到 ['/data/a.txt', '/data/sub/b.log', ...]

臨時腳本用遞迴函數最快;長期服務、大目錄、高併發請改用 SPL 迭代器 + 快取 + 非同步處理,架構更穩健。

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