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

PHP 遞迴計算目錄總大小:RecursiveDirectoryIterator 實作

     編輯:PHP 相關知識

使用 SPL RecursiveDirectoryIterator 搭配 RecursiveIteratorIterator 可輕鬆遞迴遍歷目錄樹,累加每個檔案大小,取得目錄總佔用空間。比傳統 opendir/readdir 遞迴函式更簡潔、效能更好。

基本實作

<?php
function getDirectorySize(string $path): int {
    if (!is_dir($path)) {
        throw new InvalidArgumentException("非目錄: $path");
    }
    $total = 0;
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)
    );
    foreach ($iterator as $file) {
        if ($file->isFile()) {
            $total += $file->getSize();
        }
    }
    return $total;
}

// 使用
$size = getDirectorySize('/var/www/html');
echo "總大小: " . formatBytes($size) . "\n";

function formatBytes(int $bytes): string {
    $units = ['B', 'KB', 'MB', 'GB', 'TB'];
    $i = 0;
    while ($bytes >= 1024 && $i < count($units)-1) {
        $bytes /= 1024;
        $i++;
    }
    return round($bytes, 2) . ' ' . $units[$i];
}
?>

進階:含子目錄大小分解報表

function getDirSizeDetails(string $path): array {
    $result = ['total' => 0, 'dirs' => [], 'files' => 0];
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
        RecursiveIteratorIterator::SELF_FIRST
    );
    foreach ($iterator as $file) {
        if ($file->isDir()) {
            $result['dirs'][$file->getPathname()] = 0; // 佔位
        } elseif ($file->isFile()) {
            $size = $file->getSize();
            $result['total'] += $size;
            $result['files']++;
            // 累加至各父目錄(簡化版)
            $dir = $file->getPath();
            while ($dir !== $path && $dir !== '/') {
                $result['dirs'][$dir] = ($result['dirs'][$dir] ?? 0) + $size;
                $dir = dirname($dir);
            }
            $result['dirs'][$path] = ($result['dirs'][$path] ?? 0) + $size;
        }
    }
    return $result;
}

關鍵 Flags 說明

  • FilesystemIterator::SKIP_DOTS:自動跳過 . 和 ..。
  • FilesystemIterator::CURRENT_AS_FILEINFO:預設即為 SplFileInfo,支援 getSize()、isFile()、getPathname() 等。
  • RecursiveIteratorIterator::SELF_FIRST:先處理目錄本身再處理子元素(適合建立樹狀結構)。
  • CHILD_FIRST:先處理子元素(適合刪除操作)。

效能與注意事項

  • 大量檔案(>10萬)遍歷耗時明顯,建議快取結果或使用系統指令 du -sh(Linux)。
  • 網路掛載目錄(NFS/SMB)速度極慢,避免頻繁呼叫。
  • 權限不足的目錄/檔案會拋出例外,需 try-catch 或 @ 抑制。

SPL 迭代器是 PHP 檔案系統操作的現代標準工具,程式碼可讀性與維護性遠勝傳統函式。

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