场景:各种文件的大小以字节的形式存储在数据库中。把这个大小信息格式化为千字节、兆字节和千兆字节的最好方法是什么?例如,我有一个MP3, Ubuntu显示为“5.2 MB(5445632字节)”。我如何在网页上显示这为“5.2 MB”,并有文件小于1兆字节显示为KB和文件1gb及以上显示为GB?
当前回答
灵活的解决方案:
function size($size, array $options=null) {
$o = [
'binary' => false,
'decimalPlaces' => 2,
'decimalSeparator' => '.',
'thausandsSeparator' => '',
'maxThreshold' => false, // or thresholds key
'suffix' => [
'thresholds' => ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'],
'decimal' => ' {threshold}B',
'binary' => ' {threshold}iB',
'bytes' => ' B'
]
];
if ($options !== null)
$o = array_replace_recursive($o, $options);
$base = $o['binary'] ? 1024 : 1000;
$exp = $size ? floor(log($size) / log($base)) : 0;
if (($o['maxThreshold'] !== false) &&
($o['maxThreshold'] < $exp)
)
$exp = $o['maxThreshold'];
return !$exp
? (round($size) . $o['suffix']['bytes'])
: (
number_format(
$size / pow($base, $exp),
$o['decimalPlaces'],
$o['decimalSeparator'],
$o['thausandsSeparator']
) .
str_replace(
'{threshold}',
$o['suffix']['thresholds'][$exp],
$o['suffix'][$o['binary'] ? 'binary' : 'decimal']
)
);
}
var_dump(size(disk_free_space('/')));
// string(8) "14.63 GB"
var_dump(size(disk_free_space('/'), ['binary' => true]));
// string(9) "13.63 GiB"
var_dump(size(disk_free_space('/'), ['maxThreshold' => 2]));
// string(11) "14631.90 MB"
var_dump(size(disk_free_space('/'), ['binary' => true, 'maxThreshold' => 2]));
// string(12) "13954.07 MiB"
其他回答
灵活的解决方案:
function size($size, array $options=null) {
$o = [
'binary' => false,
'decimalPlaces' => 2,
'decimalSeparator' => '.',
'thausandsSeparator' => '',
'maxThreshold' => false, // or thresholds key
'suffix' => [
'thresholds' => ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'],
'decimal' => ' {threshold}B',
'binary' => ' {threshold}iB',
'bytes' => ' B'
]
];
if ($options !== null)
$o = array_replace_recursive($o, $options);
$base = $o['binary'] ? 1024 : 1000;
$exp = $size ? floor(log($size) / log($base)) : 0;
if (($o['maxThreshold'] !== false) &&
($o['maxThreshold'] < $exp)
)
$exp = $o['maxThreshold'];
return !$exp
? (round($size) . $o['suffix']['bytes'])
: (
number_format(
$size / pow($base, $exp),
$o['decimalPlaces'],
$o['decimalSeparator'],
$o['thausandsSeparator']
) .
str_replace(
'{threshold}',
$o['suffix']['thresholds'][$exp],
$o['suffix'][$o['binary'] ? 'binary' : 'decimal']
)
);
}
var_dump(size(disk_free_space('/')));
// string(8) "14.63 GB"
var_dump(size(disk_free_space('/'), ['binary' => true]));
// string(9) "13.63 GiB"
var_dump(size(disk_free_space('/'), ['maxThreshold' => 2]));
// string(11) "14631.90 MB"
var_dump(size(disk_free_space('/'), ['binary' => true, 'maxThreshold' => 2]));
// string(12) "13954.07 MiB"
伪代码:
$base = log($size) / log(1024);
$suffix = array("", "k", "M", "G", "T")[floor($base)];
return pow(1024, $base - floor($base)) . $suffix;
根据Leo的回答,添加
对否定的支持 支持0 < value < 1(例如:0.2,会导致log(value) =负数)
如果你想要最大单位Mega,更改$units =爆炸(' ',' K M');
function formatUnit($value, $precision = 2) {
$units = explode(' ', ' K M G T P E Z Y');
if ($value < 0) {
return '-' . formatUnit(abs($value));
}
if ($value < 1) {
return $value . $units[0];
}
$power = min(
floor(log($value, 1024)),
count($units) - 1
);
return round($value / pow(1024, $power), $precision) . $units[$power];
}
我将所有输入转换为字节,从而转换为所需的任何输出。此外,我使用了一个辅助函数来获取以1000或1024为基数的基数,但让它灵活地决定在流行类型上使用1024(没有' I ',比如MB而不是MiB)。
public function converte_binario($size=0,$format_in='B',$format_out='MB',$force_in_1024=false,$force_out_1024=false,$precisao=5,$return_format=true,$decimal=',',$centena=''){
$out = false;
if( (is_numeric($size)) && ($size>0)){
$in_data = $this->converte_binario_aux($format_in,$force_in_1024);
$out_data = $this->converte_binario_aux($format_out,$force_out_1024);
// se formato de entrada e saída foram encontrados
if( ((isset($in_data['sucesso'])) && ($in_data['sucesso']==true)) && ((isset($out_data['sucesso'])) && ($out_data['sucesso']==true))){
// converte formato de entrada para bytes.
$size_bytes_in = $size * (pow($in_data['base'], $in_data['pot']));
$size_byte_out = (pow($out_data['base'], $out_data['pot']));
// transforma bytes na unidade de destino
$out = number_format($size_bytes_in / $size_byte_out,$precisao,$decimal,$centena);
if($return_format){
$out .= $format_out;
}
}
}
return $out;
}
public function converte_binario_aux($format=false,$force_1024=false){
$out = [];
$out['sucesso'] = false;
$out['base'] = 0;
$out['pot'] = 0;
if((is_string($format) && (strlen($format)>0))){
$format = trim(strtolower($format));
$units_1000 = ['b','kb' ,'mb' ,'gb' ,'tb' ,'pb' ,'eb' ,'zb' ,'yb' ];
$units_1024 = ['b','kib','mib','gib','tib','pib','eib','zib','yib'];
$pot = array_search($format,$units_1000);
if( (is_numeric($pot)) && ($pot>=0)){
$out['pot'] = $pot;
$out['base'] = 1000;
$out['sucesso'] = true;
}
else{
$pot = array_search($format,$units_1024);
if( (is_numeric($pot)) && ($pot>=0)){
$out['pot'] = $pot;
$out['base'] = 1024;
$out['sucesso'] = true;
}
}
if($force_1024){
$out['base'] = 1024;
}
}
return $out;
}
我知道现在回答这个问题可能有点晚了,但是,更多的数据不会杀死一个人。这是一个非常快速的函数:
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';
}
编辑:我更新了我的帖子,包括由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';
}
推荐文章
- 原则-如何打印出真正的sql,而不仅仅是准备好的语句?
- 如何从关联PHP数组中获得第一项?
- PHP/MySQL插入一行然后获取id
- 我如何排序一个多维数组在PHP
- 如何在PHP中截断字符串最接近于一定数量的字符?
- PHP错误:“zip扩展名和unzip命令都没有,跳过。”
- Nginx提供下载。php文件,而不是执行它们
- Json_encode()转义正斜杠
- 如何在PHP中捕获cURL错误
- 如何要求一个分叉与作曲家?
- 如何在php中创建可选参数?
- 在文本文件中创建或写入/追加
- 为什么PHP的json_encode函数转换UTF-8字符串为十六进制实体?
- 如何从一个查询插入多行使用雄辩/流利
- 在PHP单元测试执行期间,如何在CLI中输出?