<?php
/**
* 遞歸計算目錄總大小(字節)
* @param string $dir 目錄路徑
* @return int|false 總字節數,失敗返回 false
*/
function dirsize(string $dir): int|false {
if (!is_dir($dir)) return false;
$dh = @opendir($dir);
if (!$dh) return false;
$size = 0;
while (($file = @readdir($dh)) !== false) {
if ($file === '.' || $file === '..') continue;
$path = $dir . DIRECTORY_SEPARATOR . $file;
if (is_dir($path)) {
$subSize = dirsize($path);
if ($subSize !== false) $size += $subSize;
} elseif (is_file($path)) {
$size += filesize($path);
}
// 忽略符號鏈接、設備文件等特殊類型
}
@closedir($dh);
return $size;
}
// 使用示例
$dirPath = './my_files';
$bytes = dirsize($dirPath);
if ($bytes !== false) {
$mb = round($bytes / 1024 / 1024, 2);
echo "目錄大小: {$mb} MB";
} else {
echo "目錄不存在或無權限讀取";
}
@,改用 try-catch 或檢查 error_get_last() 記錄日誌。is_dir() 對鏈接返回目標類型,可能導致重複計算或死循環。生產級代碼應用 is_link() 排除或記錄已訪問 inode。// 使用 RecursiveIteratorIterator + SplFileInfo(更優雅、可迭代)
function dirsizeModern(string $dir): int {
$total = 0;
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)
);
foreach ($iterator as $file) {
if ($file->isFile()) $total += $file->getSize();
}
return $total;
}
優點:自動處理權限異常、支援過濾器、代碼更聲明式。缺點:極深目錄結構可能超過遞歸限制(可調整 xdebug.max_nesting_level)。
du -sh 系統命令(最快,需 exec 權限)