统计一个目录占了多少空间、有多少文件,是磁盘清理与备份任务的常见前置步骤。PHP 用 scandir 配合递归可以轻松实现,注意目录里的 . 与 .. 要跳过,否则会死循环。
完整代码
<?php
/**
* 递归统计目录:返回 [size 字节, count 文件数]
*/
function dirStat(string $dir): array
{
$size = 0;
$count = 0;
$items = scandir($dir);
if ($items === false) {
return ["size" => 0, "count" => 0];
}
foreach ($items as $item) {
if ($item === "." || $item === "..") {
continue;
}
$full = rtrim($dir, "/") . "/" . $item;
if (is_dir($full)) {
$sub = dirStat($full);
$size += $sub["size"];
$count += $sub["count"];
} else {
$size += filesize($full);
$count++;
}
}
return ["size" => $size, "count" => $count];
}
/**
* 字节数格式化为可读容量
*/
function formatSize(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];
}
$stat = dirStat("D:/www/site/upload");
echo "文件数:" . $stat["count"] . PHP_EOL;
echo "总大小:" . formatSize($stat["size"]) . PHP_EOL;
?>注意事项
- Linux 下软链接可能造成递归死循环,必要时用 is_link 拦截;
- filesize 对超大文件返回类型注意使用 64 位 PHP,避免溢出;
- 目录数量大时优先使用 RecursiveIteratorIterator 迭代器,内存占用更低。
小结
递归统计逻辑清晰易读,适合中小目录;需要快速展示全盘容量分布时,改为迭代器加按目录聚合更高效。
评论(0)
暂无评论,快来抢沙发吧~