场景:各种文件的大小以字节的形式存储在数据库中。把这个大小信息格式化为千字节、兆字节和千兆字节的最好方法是什么?例如,我有一个MP3, Ubuntu显示为“5.2 MB(5445632字节)”。我如何在网页上显示这为“5.2 MB”,并有文件小于1兆字节显示为KB和文件1gb及以上显示为GB?


当前回答

下面是Drupal format_size函数的简化实现:

/**
 * Generates a string representation for the given byte count.
 *
 * @param $size
 *   A size in bytes.
 *
 * @return
 *   A string representation of the size.
 */
function format_size($size) {
  if ($size < 1024) {
    return $size . ' B';
  }
  else {
    $size = $size / 1024;
    $units = ['KB', 'MB', 'GB', 'TB'];
    foreach ($units as $unit) {
      if (round($size, 2) >= 1024) {
        $size = $size / 1024;
      }
      else {
        break;
      }
    }
    return round($size, 2) . ' ' . $unit;
  }
}

其他回答

这是Kohana的实现,你可以使用它:

public static function bytes($bytes, $force_unit = NULL, $format = NULL, $si = TRUE)
{
    // Format string
    $format = ($format === NULL) ? '%01.2f %s' : (string) $format;

    // IEC prefixes (binary)
    if ($si == FALSE OR strpos($force_unit, 'i') !== FALSE)
    {
        $units = array('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB');
        $mod   = 1024;
    }
    // SI prefixes (decimal)
    else
    {
        $units = array('B', 'kB', 'MB', 'GB', 'TB', 'PB');
        $mod   = 1000;
    }

    // Determine unit to use
    if (($power = array_search((string) $force_unit, $units)) === FALSE)
    {
        $power = ($bytes > 0) ? floor(log($bytes, $mod)) : 0;
    }

    return sprintf($format, $bytes / pow($mod, $power), $units[$power]);
}

我自己的实现,从整数大小获得格式化文件大小。简单易懂,易于扩展,以适应更大的文件-只需遵循模式。

<?php

function getFormattedFileSize($size, $precision) 
{
    switch (true) 
    {
        case ($size/1024 < 1):
            return $size.'B';
        case ($size/pow(1024, 2) < 1):
            return round($size/1024, $precision).'KB';
        case ($size/pow(1024, 3) < 1):
            return round($size/pow(1024, 2), $precision).'MB';
        case ($size/pow(1024, 4) < 1):
            return round($size/pow(1024, 3), $precision).'GB';
        case ($size/pow(1024, 5) < 1):
            return round($size/pow(1024, 4), $precision).'TB';
        default:
            return 'Error: invalid input or file is too large.';
    }
}

kb除以1024,mb除以1024^2,GB除以1024^3。就这么简单。

另一个压缩实现,可以转换为以1024为基数(二进制)或以1000为基数(十进制),也适用于难以置信的大数字,因此使用bc库:

function renderSize($byte,$precision=2,$mibi=true)
{
    $base = (string)($mibi?1024:1000);
    $labels = array('K','M','G','T','P','E','Z','Y');
    for($i=8;$i>=1;$i--)
        if(bccomp($byte,bcpow($base, $i))>=0)
            return bcdiv($byte,bcpow($base, $i), $precision).' '.$labels[$i-1].($mibi?'iB':'B');
    return $byte.' Byte';
}

如果需要短代码,请使用此函数

BCDIV()

$size = 11485760;
echo bcdiv($size, 1048576, 0); // return: 10

echo bcdiv($size, 1048576, 2); // return: 10,9

echo bcdiv($size, 1048576, 2); // return: 10,95

echo bcdiv($size, 1048576, 3); // return: 10,953