Переводим байты в человекочитаемый вид
Поводом для статьи послужила моя забывчивость, когда мне очень понадобилась давно написанная функция и я все никак не мог ее найти среди множества сайтов.
Конечно, я ее нашел, но времени ушло немало, для такой скромной функции, а посему я решил постить в этот блог свои подручные функции написанные на PHP, что-бы было одно место, где искать.
Функция переводит числовые значения в байтах в удобочитаемый вид. Вот примеры вывода:
bytes2readable(1000); // 0.98 КБ
bytes2readable(10000); // 9.77 КБ
bytes2readable(123456789); // 117.74 МБ
bytes2readable(109951162776); // 102.4 ГБ
bytes2readable(9000511627776); // 8.19 ТБ
bytes2readable(5000511627776954); // 4.44 ПБ
bytes2readable(PHP_INT_MAX); // 8 ЭБ
А вот и сама функция:
<?php
function bytes2readable($v, $divisor = 1024, $precision = 2, $l = 0) {
$label = ['К', 'М', 'Г', 'Т', 'П', 'Э'];
$val = $v / $divisor;
$floorVal = floor($val);
return $floorVal >= $divisor ?
bytes2readable($floorVal, $divisor, $precision, ++$l) :
sprintf('%s %sБ', round($val, $precision), $label[$l]);
}
?>
здесь:
$divisor - делитель (количество байт в КБайте, по умолчанию 1024)
$label - массив названий градаций Ваших пороговых значений
$precision - точность округления после запятой
Что мне не нравится в этой функции?
- Она ограничена разрядностью системы, поэтому максимальное значение, которое мы можем корректно вычислить с ее помощью в архитектуре x64 равно 8 ЭБ (если необходимо работать с большими числами, то используем библиотеку BCMath, либо библиотеку GMP)
- Массив $label рекурсивно множится в памяти, что не есть хорошо
- Всегда помним правило, что там, где можно обойтись без рекурсии, необходимо всё делать без нее, так как никогда не знаешь, когда наткнешься на фатальную ошибку Stack overflow, которая в PHP выглядит как Fatal error: Maximum function nesting level of '100' reached, aborting!
Отлично !
В блогролл ! =)
Пользуйтесь на здоровье :)
Когда-то писал подобную функцию, конечно она не так элегантна как ваша.
Но тогда в голову мне пришла мысль, что 988 байт лучше записывать как 988 байт, а не 0,96 КБ. В моей функции был порог 8 192 (8000 = 8 000 байт, 8 200 = 8,00 КБ и т.д.)
Мысль понятна, бывают и такие случаи. За элегантность спасибо.