将字节格式化为千字节,兆字节,千兆字节

lee*_*ers 171 php

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

Leo*_*Leo 302

function formatBytes($bytes, $precision = 2) { 
    $units = array('B', 'KB', 'MB', 'GB', 'TB'); 

    $bytes = max($bytes, 0); 
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); 
    $pow = min($pow, count($units) - 1); 

    // Uncomment one of the following alternatives
    // $bytes /= pow(1024, $pow);
    // $bytes /= (1 << (10 * $pow)); 

    return round($bytes, $precision) . ' ' . $units[$pow]; 
} 
Run Code Online (Sandbox Code Playgroud)

(摘自php.net,还有很多其他的例子,但我最喜欢这个:-)

  • 实际上,它是"KiB","MiB","GiB"和"TiB",因为你除以"1024".如果你除以'1000`,它将没有`i`. (20认同)
  • 如果你使用`$ bytes/=(1 <<(10*$ pow))`等,我会更喜欢它.:-P (7认同)
  • 在那里你去:D(个人而言,我不喜欢按位运算,因为如果你不习惯它很难理解......) (5认同)
  • @Justin那是因为9287695/1024/1024确实是8,857 :) (3认同)
  • 取消注释以下备选方案之一是我5分钟没有注意到的事情... (3认同)
  • @yogur,如果 $bytes 是负值,它会将其设置为 0。 (2认同)

Joh*_*man 203

这是Chris Jester-Young的实现,我见过最干净,结合了php.net和精确的参数.

function formatBytes($size, $precision = 2)
{
    $base = log($size, 1024);
    $suffixes = array('', 'K', 'M', 'G', 'T');   

    return round(pow(1024, $base - floor($base)), $precision) .' '. $suffixes[floor($base)];
}

echo formatBytes(24962496);
// 23.81M

echo formatBytes(24962496, 0);
// 24M

echo formatBytes(24962496, 4);
// 23.8061M
Run Code Online (Sandbox Code Playgroud)

  • 它有2个错误 - 添加1到(至少很小)文件大小 - 不使用0(返回NAN) (8认同)
  • *一个梦想***:**`$ suffixes = array('B','kB','MB','GB','TB','PB','EB','ZB','YB ');`我想要一个Yottabyte硬盘!***: - P*** (3认同)

Chr*_*ung 96

伪代码:

$base = log($size) / log(1024);
$suffix = array("", "k", "M", "G", "T")[floor($base)];
return pow(1024, $base - floor($base)) . $suffix;
Run Code Online (Sandbox Code Playgroud)


rye*_*guy 15

这是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]);
}
Run Code Online (Sandbox Code Playgroud)


Von*_*der 14

对于kb,将其除以1024,对于mb,将1024 ^ 2除以GB,对于GB,将其除以1024 ^ 3.就如此容易.

  • 否决,因为 a) 它实际上是错误的(参见 ISO 80000-13),b) 没有以代码形式提供任何真正的解决方案。 (3认同)

gua*_*ari 8

只是我的另类,简短而干净:

/**
 * @param int $bytes Number of bytes (eg. 25907)
 * @param int $precision [optional] Number of digits after the decimal point (eg. 1)
 * @return string Value converted with unit (eg. 25.3KB)
 */
function formatBytes($bytes, $precision = 2) {
    $unit = ["B", "KB", "MB", "GB"];
    $exp = floor(log($bytes, 1024)) | 0;
    return round($bytes / (pow(1024, $exp)), $precision).$unit[$exp];
}
Run Code Online (Sandbox Code Playgroud)

或者,更愚蠢和有效:

function formatBytes($bytes, $precision = 2) {
    if ($bytes > pow(1024,3)) return round($bytes / pow(1024,3), $precision)."GB";
    else if ($bytes > pow(1024,2)) return round($bytes / pow(1024,2), $precision)."MB";
    else if ($bytes > 1024) return round($bytes / 1024, $precision)."KB";
    else return ($bytes)."B";
}
Run Code Online (Sandbox Code Playgroud)


小智 7

如果你想要一个简短的代码,请使用此功能

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
Run Code Online (Sandbox Code Playgroud)


Dav*_*ger 6

我知道回答这个问题可能有点迟,但更多数据不会杀死某人.这是一个非常快速的功能:

function format_filesize($B, $D=2){
    $S = 'BkMGTPEZY';
    $F = floor((strlen($B) - 1) / 3);
    return sprintf("%.{$D}f", $B/pow(1024, $F)).' '.@$S[$F].'B';
}
Run Code Online (Sandbox Code Playgroud)

编辑:我更新了我的帖子,包括camomileCase提出的修复:

function format_filesize($B, $D=2){
    $S = 'kMGTPEZY';
    $F = floor((strlen($B) - 1) / 3);
    return sprintf("%.{$D}f", $B/pow(1024, $F)).' '.@$S[$F-1].'B';
}
Run Code Online (Sandbox Code Playgroud)

  • 对于较小的 $B 值,您会得到一个双 B (BB),作为解决方法,您可以制作“$S = 'kMGTPEZY'”,而不是“@$S[$F]”,而是“@$S[$” F-1]”。 (2认同)
  • @camomileCase 两年半后 - 我更新了我的答案。谢谢。 (2认同)

Seb*_*lin 6

功能简单

function formatBytes($size, $precision = 0){
    $unit = ['Byte','KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];

    for($i = 0; $size >= 1024 && $i < count($unit)-1; $i++){
        $size /= 1024;
    }

    return round($size, $precision).' '.$unit[$i];
}

echo formatBytes('1876144', 2);
//returns 1.79 MiB
Run Code Online (Sandbox Code Playgroud)