Расставляй правильно приоритеты и не отвлекайся на мелочи

Переводим байты в человекочитаемый вид

Поводом для статьи послужила моя забывчивость, когда мне очень понадобилась давно написанная функция и я все никак не мог ее найти среди множества сайтов.
Конечно, я ее нашел, но времени ушло немало, для такой скромной функции, а посему я решил постить в этот блог свои подручные функции написанные на 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 - точность округления после запятой

Что мне не нравится в этой функции?

  1. Она ограничена разрядностью системы, поэтому максимальное значение, которое мы можем корректно вычислить с ее помощью в архитектуре x64 равно 8 ЭБ (если необходимо работать с большими числами, то используем библиотеку BCMath, либо библиотеку GMP)
  2. Массив $label рекурсивно множится в памяти, что не есть хорошо
  3. Всегда помним правило, что там, где можно обойтись без рекурсии, необходимо всё делать без нее, так как никогда не знаешь, когда наткнешься на фатальную ошибку Stack overflow, которая в PHP выглядит как Fatal error: Maximum function nesting level of '100' reached, aborting!
4 комментария на статью:
Ответить
Обязательные поля помечены *