在網頁顯示檔案大小或流量統計時,原始位元組數字難以閱讀。本文提供一個 formatSize() 遞迴函式,自動依大小切換單位 (B、KB、MB...ZB),保留兩位小數,程式碼簡潔易懂,附帶完整單位對照表與擴充建議。
formatSize()<?php
/**
* 格式化位元組大小為人類可讀字串
* @param int|float $bytes 位元組數
* @param int $times 遞迴層級 (內部使用,外部呼叫請忽略)
* @return string 如 "19.71 MB"
*/
function formatSize($bytes, $times = 0) {
if ($bytes >= 1024) {
return formatSize($bytes / 1024, $times + 1);
}
$units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
$unit = $units[$times] ?? '未知單位';
return sprintf('%.2f %s', $bytes, $unit);
}
// === 使用範例 ===
echo formatSize(20667564) . "\n"; // 19.71 MB
echo formatSize(1024) . "\n"; // 1.00 KB
echo formatSize(1536) . "\n"; // 1.50 KB
echo formatSize(1073741824) . "\n"; // 1.00 GB
echo formatSize(0) . "\n"; // 0.00 B
echo formatSize(500) . "\n"; // 500.00 B
?>
| 單位 | 符號 | 倍數 (1024^n) | 約略十進制 | 中文唸法 |
|---|---|---|---|---|
| 位元組 | B | 1024^0 | 1 | 位元組 |
| 千位元組 | KB / KiB | 1024^1 | 1,024 | 千 / 奇 |
| 百萬位元組 | MB / MiB | 1024^2 | 1,048,576 | 兆 / 百萬 |
| 十億位元組 | GB / GiB | 1024^3 | 1,073,741,824 | 吉 / 十億 |
| 兆兆位元組 | TB / TiB | 1024^4 | 1.0995e12 | 太 / 兆兆 |
| 拍位元組 | PB / PiB | 1024^5 | 1.1259e15 | 拍 / 千兆兆 |
| 艾位元組 | EB / EiB | 1024^6 | 1.1529e18 | 艾 / 百萬兆兆 |
| 澤位元組 | ZB / ZiB | 1024^7 | 1.1806e21 | 澤 / 十億兆兆 |
| 堯位元組 | YB / YiB | 1024^8 | 1.2089e24 | 堯 / 兆兆兆兆 |
註:國際標準建議使用 KiB、MiB、GiB (1024 進制) 與 KB、MB、GB (1000 進制) 區分,實務上常混用,請依專案規範決定。
<?php
function formatSizeAdvanced($bytes, $binary = true, $decimals = 2) {
if ($bytes == 0) return '0 B';
$system = $binary ? 1024 : 1000;
$suffix = $binary ? ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
$exp = (int)floor(log($bytes, $system));
$exp = min($exp, count($suffix) - 1);
$value = $bytes / pow($system, $exp);
return round($value, $decimals) . ' ' . $suffix[$exp];
}
// 1024 進制 (預設)
echo formatSizeAdvanced(1536) . "\n"; // 1.5 KiB
// 1000 進制 (硬碟廠商常用)
echo formatSizeAdvanced(1536, false) . "\n"; // 1.54 KB
?>
<?php
function formatSizeLoop($bytes, $decimals = 2) {
$units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
$i = 0;
while ($bytes >= 1024 && $i < count($units) - 1) {
$bytes /= 1024;
$i++;
}
return round($bytes, $decimals) . ' ' . $units[$i];
}
// 效能較佳,適合大量資料格式化 (如檔案列表數千筆)
?>
formatSize($uploaded) . ' / ' . formatSize($total)<?php
function formatSizeI18n($bytes, $locale = 'zh_TW') {
$units = [
'zh_TW' => ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
'zh_CN' => ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
'en_US' => ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
'ja_JP' => ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
];
$unitList = $units[$locale] ?? $units['en_US'];
$i = 0;
while ($bytes >= 1024 && $i < count($unitList) - 1) {
$bytes /= 1024;
$i++;
}
return number_format($bytes, 2, '.', '') . ' ' . $unitList[$i];
}
?>
將此函式納入專案共用工具庫,統一全站檔案大小顯示格式,提升使用者體驗與程式碼一致性。