function humanFileSize($size) { if ($size >= 1073741824) { $fileSize = round($size / 1024 / 1024 / 1024,1) . 'GB'; } elseif ($size >= 1048576) { $fileSize = round($size / 1024 / 1024,1) . 'MB'; } elseif($size >= 1024) { $fileSize = round($size / 1024,1) . 'KB'; } else { $fileSize = $size . ' bytes'; } return $fileSize; }
… отлично работает, за исключением: я не могу вручную выбрать, в каком формате мне нужно отображать, скажем, я хочу показывать в МБ только размер файла. В настоящее время, если он находится в диапазоне GB, он будет отображаться только в GB.
Кроме того, как ограничить десятичное число до 2?
Попробуйте что-то вроде этого:
function humanFileSize($size,$unit="") { if( (!$unit && $size >= 1<<30) || $unit == "GB") return number_format($size/(1<<30),2)."GB"; if( (!$unit && $size >= 1<<20) || $unit == "MB") return number_format($size/(1<<20),2)."MB"; if( (!$unit && $size >= 1<<10) || $unit == "KB") return number_format($size/(1<<10),2)."KB"; return number_format($size)." bytes"; }
Отличный пример Джеффри Самбелса :
function human_filesize($bytes, $dec = 2) { $size = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); $factor = floor((strlen($bytes) - 1) / 3); return sprintf("%.{$dec}f", $bytes / pow(1024, $factor)) . @$size[$factor]; } print human_filesize(filesize('example.zip'));
Я использую этот метод:
function byteConvert($bytes) { if ($bytes == 0) return "0.00 B"; $s = array('B', 'KB', 'MB', 'GB', 'TB', 'PB'); $e = floor(log($bytes, 1024)); return round($bytes/pow(1024, $e), 2).$s[$e]; }
отлично работает в o (1).
Чтобы расширить ответ на вопрос Vaidas, вот как вы должны это сделать, чтобы учитывать новые стандарты IEC:
function human_readable_bytes($bytes, $decimals = 2, $system = 'binary') { $mod = ($system === 'binary') ? 1024 : 1000; $units = array( 'binary' => array( 'B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB', ), 'metric' => array( 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', ), ); $factor = floor((strlen($bytes) - 1) / 3); return sprintf("%.{$decimals}f%s", $bytes / pow($mod, $factor), $units[$system][$factor]); }
Технически, в соответствии со спецификациями для устройств хранения данных, вы должны использовать стандартную метрическую систему (поэтому конвертер Google показывает kB -> MB как mod 1000 вместо 1024).
function getHumanReadableSize($size, $unit = null, $decemals = 2) { $byteUnits = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; if (!is_null($unit) && !in_array($unit, $byteUnits)) { $unit = null; } $extent = 1; foreach ($byteUnits as $rank) { if ((is_null($unit) && ($size < $extent <<= 10)) || ($rank == $unit)) { break; } } return number_format($size / ($extent >> 10), $decemals) . $rank; }
Если версия php ниже 5.4 использует $byteUnits = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
Мне нужна функция, которая возвращала файлы, подобные Windows, и, на удивление, я вообще ничего не мог найти. Хуже того, некоторые здесь и в другом месте разбиты тем, что они предполагают 1KB = 1000B.
Поэтому я закодировал один! Плюс две вспомогательные функции. Вот они:
// Returns a size in a human-readable form from a byte count. function humanSize($bytes) { if ($bytes < 1024) return "$bytes Bytes"; $units = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; foreach ($units as $i => $unit) { // The reason for this threshold is to avoid eg, "1000 KB", // instead jumping from eg, "999 KB" to "0.97 MB". $multiplier = pow(1024, $i + 1); $threshold = $multiplier * 1000; if ($bytes < $threshold) { $size = formatToMinimumDigits($bytes / $multiplier, false); return "$size $unit"; } } } // Efficiently calculates how many digits the integer portion of a number has. function digits($number) { // Yes, I could convert to string and count the characters, // but this is faster and cooler. $log = log10($number); if ($log < 0) return 1; return floor($log) + 1; } // Formats a number to a minimum amount of digits. // In other words, makes sure that a number has at least $digits on it, even if // that means introducing redundant decimal zeroes at the end, or rounding the // ones present exceeding the $digits count when combined with the integers. // For example: // formatToMinimumDigits(10) // 10.0 // formatToMinimumDigits(1.1) // 1.10 // formatToMinimumDigits(12.34) // 12.3 // formatToMinimumDigits(1.234) // 1.23 // formatToMinimumDigits(1.203) // 1.20 // formatToMinimumDigits(123.4) // 123 // formatToMinimumDigits(100) // 100 // formatToMinimumDigits(1000) // 1000 // formatToMinimumDigits(1) // 1.00 // formatToMinimumDigits(1.002) // 1.00 // formatToMinimumDigits(1.005) // 1.01 // formatToMinimumDigits(1.005, false) // 1.00 // This is primarily useful for generating human-friendly numbers. function formatToMinimumDigits($value, $round = true, $digits = 3) { $integers = floor($value); $decimalsNeeded = $digits - digits($integers); if ($decimalsNeeded < 1) { return $integers; } else { if ($round) { // This relies on implicit type casting of float to string. $parts = explode('.', round($value, $decimalsNeeded)); // We re-declare the integers because they may change // after we round the number. $integers = $parts[0]; } else { // Again, implicit type cast to string. $parts = explode('.', $value); } // And because of the implicit type cast, we must guard against // 1.00 becoming 1, thus not exploding the second half of it. $decimals = isset($parts[1]) ? $parts[1] : '0'; $joined = "$integers.$decimals".str_repeat('0', $digits); return substr($joined, 0, $digits + 1); } }
Использование так же просто, как humanSize(123456789)
.
Вы можете изменить свою функцию, чтобы заполнить всю вашу потребность в принудительной установке единицы, если она задана, и настроить точность.
function humanFileSize($size, $precision = 1, $show = "") { $b = $size; $kb = round($size / 1024, $precision); $mb = round($kb / 1024, $precision); $gb = round($mb / 1024, $precision); if($kb == 0 || $show == "B") { return $b . " bytes"; } else if($mb == 0 || $show == "KB") { return $kb . "KB"; } else if($gb == 0 || $show == "MB") { return $mb . "MB"; } else { return $gb . "GB"; } } //Test with different values echo humanFileSize(1038) . "<br />"; echo humanFileSize(103053, 0) . "<br />"; echo humanFileSize(103053) . "<br />"; echo humanFileSize(1030544553) . "<br />"; echo humanFileSize(1030534053405, 2, "GB") . "<br />"; ;
Вот работающая функция до Yottabyte:
function DisplayFileSize($size, $unit = false, $precision = 2){ $b = $size; $kb = round($size / 1024, $precision); $mb = round($kb / 1024, $precision); $gb = round($mb / 1024, $precision); $tb = round($gb / 1024, $precision); $pb = round($tb / 1024, $precision); $eb = round($pb / 1024, $precision); $zb = round($eb / 1024, $precision); $yb = round($zb / 1024, $precision); if((!$unit && floor($kb) == 0) || $unit == "b") { return array("value" => FormatNumber($b), "unit" => "bytes"); } else if((!$unit && floor($mb) == 0) || $unit == "kb") { return array("value" => FormatNumber($kb, 2), "unit" => "Kb"); } else if((!$unit && floor($gb) == 0) || $unit == "mb") { return array("value" => FormatNumber($mb, 2), "unit" => "Mb"); } else if((!$unit && floor($tb) == 0) || $unit == "gb") { return array("value" => FormatNumber($gb, 2), "unit" => "Gb"); } else if((!$unit && floor($pb) == 0) || $unit == "tb") { return array("value" => FormatNumber($tb, 2), "unit" => "Tb"); } else if((!$unit && floor($eb) == 0) || $unit == "pb") { return array("value" => FormatNumber($pb, 2), "unit" => "Pb"); } else if((!$unit && floor($zb) == 0) || $unit == "eb") { return array("value" => FormatNumber($eb, 2), "unit" => "Eb"); } else if((!$unit && floor($yb) == 0) || $unit == "zb") { return array("value" => FormatNumber($zb, 2), "unit" => "Zb"); } else { return array("value" => FormatNumber($yb, 2), "unit" => "Yb"); }
}