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

PHP 遞歸計算目錄大小並自動轉換單位:完整函數庫與效能優化建議

     編輯:PHP 相關知識

PHP 遞歸計算目錄大小並自動轉換單位:完整函數庫與效能優化建議

核心實作:遞歸掃描 + 單位轉換

<?php
/**
 * 遞歸計算目錄總大小(位元組)
 * @param string $dir 絕對路徑
 * @return int 總位元組數
 */
function getDirSize($dir) {
    $dir = rtrim($dir, '/');
    if (!is_dir($dir) || !is_readable($dir)) {
        return 0;
    }
    
    $size = 0;
    $handle = opendir($dir);
    while (($entry = readdir($handle)) !== false) {
        if ($entry === '.' || $entry === '..') continue;
        $path = $dir . '/' . $entry;
        if (is_dir($path)) {
            $size += getDirSize($path);
        } elseif (is_file($path)) {
            $size += filesize($path);
        }
        // 忽略連結、特殊檔案
    }
    closedir($handle);
    return $size;
}

/**
 * 位元組轉人類可讀格式
 * @param int $bytes
 * @param int $precision 小數位數
 * @return string
 */
function formatBytes($bytes, $precision = 2) {
    $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
    $bytes = max($bytes, 0);
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
    $pow = min($pow, count($units) - 1);
    $value = $bytes / (1024 ** $pow);
    return round($value, $precision) . ' ' . $units[$pow];
}

// 使用範例
$targetDir = '/var/www/html/project';
$totalBytes = getDirSize($targetDir);
echo "目錄大小: " . formatBytes($totalBytes); 
// 輸出範例: 目錄大小: 12.34 MB

效能優化關鍵點

  1. 避免重複 stat 系統呼叫:filesize() 會觸發 stat,可配合 SplFileInfo 快取
  2. 使用 scandir() 替代 opendir/readdir:單次系統呼叫取得所有項目,減少上下文切換
  3. 迭代器模式:RecursiveDirectoryIterator + RecursiveIteratorIterator 記憶體效率更佳

現代化寫法(PHP 5.5+)

function getDirSizeModern($dir) {
    $size = 0;
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS)
    );
    foreach ($iterator as $file) {
        if ($file->isFile()) {
            $size += $file->getSize();
        }
    }
    return $size;
}

大型目錄的進階策略

  • 快取機制:將計算結果存入 Redis/檔案,設定 TTL(如 1 小時),避免重複掃描
  • 非同步計算:透過 Queue Worker 背景計算,前端輪詢進度
  • 排除規則:支援 .gitignore 風格排除模式(vendor/、node_modules/、*.log)
  • 磁碟配額 API:Linux 下可讀取 /proc/self/mountinfo 或使用 df 取得分區剩餘空間,比遞歸快得多

常見陷阱

  1. 符號連結循環:is_link() 檢測並跳過,或維護已訪問 inode 集合
  2. 權限不足:is_readable() 預檢,捕獲 Permission denied 繼續而非中止
  3. 整數溢位:32 位元 PHP 最大整數 2GB,大目錄需用 float 或 gmp

單行指令替代方案(Linux)

# 使用系統工具極速計算(需 shell_exec 權限)
$bytes = (int)shell_exec("du -sb " . escapeshellarg($dir) . " | awk '{print \$1}'");
echo formatBytes($bytes);

根據專案規模、權限限制、即時性需求選擇適合方案;現代專案建議採用迭代器 + 快取 + 非同步架構。

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