시나리오 : 다양한 파일의 크기가 데이터베이스에 바이트로 저장됩니다. 이 크기 정보를 킬로바이트, 메가 바이트 및 기가 바이트로 포맷하는 가장 좋은 방법은 무엇입니까? 예를 들어 Ubuntu가 "5.2 MB (5445632 bytes)"로 표시하는 MP3가 있습니다. 웹 페이지에서 이것을 "5.2MB"로 표시하고 1MB 미만의 파일은 KB로 표시하고 1 기가 바이트 이상의 파일은 GB로 표시하는 방법은 무엇입니까?
시나리오 : 다양한 파일의 크기가 데이터베이스에 바이트로 저장됩니다. 이 크기 정보를 킬로바이트, 메가 바이트 및 기가 바이트로 포맷하는 가장 좋은 방법은 무엇입니까? 예를 들어 Ubuntu가 "5.2 MB (5445632 bytes)"로 표시하는 MP3가 있습니다. 웹 페이지에서 이것을 "5.2MB"로 표시하고 1MB 미만의 파일은 KB로 표시하고 1 기가 바이트 이상의 파일은 GB로 표시하는 방법은 무엇입니까?
답변:
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];
}
( php.net 에서 가져온 다른 많은 예제가 있지만이 것이 가장 좋습니다 :-)
$bytes /= (1 << (10 * $pow))
, 나는 그것을 더 좋아할 수 있습니다. :-P
KiB
, MiB
, GiB
그리고 TiB
당신에 의해 분할되어 있기 때문에 1024
. 당신이 1000
그것을 나누면 그것없이있을 것 i
입니다.
Uncomment one of the following alternatives
... 나는 5 분 동안 통지를하지 않은 것이었다
이것은 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
$suffixes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
나는 Yottabyte 하드 드라이브를 원합니다!
formatBytes(259748192, 3)
반환 259748192 MB
옳지 않다
의사 코드 :
$base = log($size) / log(1024);
$suffix = array("", "k", "M", "G", "T")[floor($base)];
return pow(1024, $base - floor($base)) . $suffix;
이것은 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]);
}
$force_unit
과 $si
같은 일을 할 것으로 보인다. $force_unit
위치를 테스트하기 때문에 "i"가있는 문자열을로 전달할 수도 있습니다 . 십진 형식도 과도합니다.
내 대안은 짧고 깨끗합니다.
/**
* @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];
}
또는 더 어리 석고 효율적입니다.
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";
}
이 질문에 대답하는 데 약간 늦었지만 더 많은 데이터가 누군가를 죽이지 않을 것이라는 것을 알고 있습니다. 다음은 매우 빠른 기능입니다.
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';
}
간단한 기능
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
유연한 솔루션 :
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 file_format_size($bytes, $decimals = 2) {
$unit_list = array('B', 'KB', 'MB', 'GB', 'PB');
if ($bytes == 0) {
return $bytes . ' ' . $unit_list[0];
}
$unit_count = count($unit_list);
for ($i = $unit_count - 1; $i >= 0; $i--) {
$power = $i * 10;
if (($bytes >> $power) >= 1)
return round($bytes / (1 << $power), $decimals) . ' ' . $unit_list[$i];
}
}
왜 당신이 다른 사람들처럼 그렇게 복잡하게 만들어야하는지 모르겠습니다.
다음 코드는 로그 기능을 사용하는 다른 솔루션보다 이해하기가 훨씬 간단하고 약 25 % 빠릅니다 (다른 매개 변수를 사용하여 20Mio.
function formatBytes($bytes, $precision = 2) {
$units = ['Byte', 'Kilobyte', 'Megabyte', 'Gigabyte', 'Terabyte'];
$i = 0;
while($bytes > 1024) {
$bytes /= 1024;
$i++;
}
return round($bytes, $precision) . ' ' . $units[$i];
}
모든 입력을 바이트로 변환하고 필요한 출력으로 변환했습니다. 또한 보조 기능을 사용하여 기본 1000 또는 1024를 얻었지만 인기있는 유형 (MiB 대신 MB와 같은 'i'없이)에서 1024를 사용하도록 결정했습니다.
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 bytesToSize($bytes) {
$sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if ($bytes == 0) return 'n/a';
$i = intval(floor(log($bytes) / log(1024)));
if ($i == 0) return $bytes . ' ' . $sizes[$i];
return round(($bytes / pow(1024, $i)),1,PHP_ROUND_HALF_UP). ' ' . $sizes[$i];
}
echo bytesToSize(10000050300);
function convertToReadableSize($size)
{
$base = log($size) / log(1024);
$suffix = array("B", "KB", "MB", "GB", "TB");
$f_base = floor($base);
return round(pow(1024, $base - floor($base)), 1) . $suffix[$f_base];
}
그냥 함수를 호출
echo convertToReadableSize(1024); // Outputs '1KB'
echo convertToReadableSize(1024 * 1024); // Outputs '1MB'
이 마지막 PHP와 함께 작동
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);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
조금 오래되었지만이 라이브러리는 테스트를 거친 강력한 변환 API를 제공합니다.
https://github.com/gabrielelana/byte-units
설치 한 후 :
\ByteUnits\Binary::bytes(1024)->format();
// Output: "1.00KiB"
그리고 다른 방향으로 변환하려면 :
\ByteUnits\Binary::parse('1KiB')->numberOfBytes();
// Output: "1024"
기본 변환 외에도 덧셈, 뺄셈, 비교 등의 방법을 제공합니다.
나는이 도서관과 관련이 없습니다.
다음은 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;
}
}
약간 늦었지만 허용되는 답변의 약간 빠른 버전은 다음과 같습니다.
function formatBytes($bytes, $precision)
{
$unit_list = array
(
'B',
'KB',
'MB',
'GB',
'TB',
);
$bytes = max($bytes, 0);
$index = floor(log($bytes, 2) / 10);
$index = min($index, count($unit_list) - 1);
$bytes /= pow(1024, $index);
return round($bytes, $precision) . ' ' . $unit_list[$index];
}
두 개의 log-e 조작 대신 단일 log-2 조작을 수행하기 때문에 더 효율적입니다.
그러나 아래에서 더 확실한 해결책을 수행하는 것이 실제로 더 빠릅니다.
function formatBytes($bytes, $precision)
{
$unit_list = array
(
'B',
'KB',
'MB',
'GB',
'TB',
);
$index_max = count($unit_list) - 1;
$bytes = max($bytes, 0);
for ($index = 0; $bytes >= 1024 && $index < $index_max; $index++)
{
$bytes /= 1024;
}
return round($bytes, $precision) . ' ' . $unit_list[$index];
}
인덱스가 적절한 단위의 바이트 수 값과 동시에 계산되기 때문입니다. 이로 인해 실행 시간이 약 35 % 단축되었습니다 (55 % 속도 증가).
1024 (이진) 또는 1000 (10 진수)으로 변환 할 수 있고 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';
}
bcpow()
형식 오류 예외의 경우가 발생합니다 $base
및 $i
문자열 값이 아니다. PHP 버전 7.0.11에서 테스트되었습니다.
내가 사용하고있는 두 제출자 코드 (이 스레드에있는 John Himmelman 코드 사용 및 Eugene Kuzmenko 코드 사용)의 메쉬를 추가 할 것이라고 생각했습니다 .
function swissConverter($value, $format = true, $precision = 2) {
//Below converts value into bytes depending on input (specify mb, for
//example)
$bytes = preg_replace_callback('/^\s*(\d+)\s*(?:([kmgt]?)b?)?\s*$/i',
function ($m) {
switch (strtolower($m[2])) {
case 't': $m[1] *= 1024;
case 'g': $m[1] *= 1024;
case 'm': $m[1] *= 1024;
case 'k': $m[1] *= 1024;
}
return $m[1];
}, $value);
if(is_numeric($bytes)) {
if($format === true) {
//Below converts bytes into proper formatting (human readable
//basically)
$base = log($bytes, 1024);
$suffixes = array('', 'KB', 'MB', 'GB', 'TB');
return round(pow(1024, $base - floor($base)), $precision) .' '.
$suffixes[floor($base)];
} else {
return $bytes;
}
} else {
return NULL; //Change to prefered response
}
}
이것은 형식을 유진의 코드를 사용 $value
(내 데이터를 변환 그래서, MB에 내 데이터를 보관 : 바이트에 10485760 MB
로 10995116277760
) - 그 다음 적절한 표시 값 (로 변환 존의 코드를 사용 10995116277760
으로 10 TB
).
나는 이것이 정말로 도움이된다는 것을 알게되었다 – 그래서 두 명의 제출자에게 감사한다!
사람 파일 크기를 얻는 매우 간단한 기능.
원본 출처 : http://php.net/manual/de/function.filesize.php#106569
코드 복사 / 붙여 넣기 :
<?php
function human_filesize($bytes, $decimals = 2) {
$sz = 'BKMGTP';
$factor = floor((strlen($bytes) - 1) / 3);
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
}
?>
사람이 읽을 수있는 메모리 크기를 다른 크기로 변환하는 자체 기능을 개발했습니다.
function convertMemorySize($strval, string $to_unit = 'b')
{
$strval = strtolower(str_replace(' ', '', $strval));
$val = floatval($strval);
$to_unit = strtolower(trim($to_unit))[0];
$from_unit = str_replace($val, '', $strval);
$from_unit = empty($from_unit) ? 'b' : trim($from_unit)[0];
$units = 'kmgtph'; // (k)ilobyte, (m)egabyte, (g)igabyte and so on...
// Convert to bytes
if ($from_unit !== 'b')
$val *= 1024 ** (strpos($units, $from_unit) + 1);
// Convert to unit
if ($to_unit !== 'b')
$val /= 1024 ** (strpos($units, $to_unit) + 1);
return $val;
}
convertMemorySize('1024Kb', 'Mb'); // 1
convertMemorySize('1024', 'k') // 1
convertMemorySize('5.2Mb', 'b') // 5452595.2
convertMemorySize('10 kilobytes', 'bytes') // 10240
convertMemorySize(2048, 'k') // By default convert from bytes, result is 2
이 함수는 "메가 바이트, MB, Mb, mb, m, 킬로바이트, K, KB, b, 테라 바이트, T ...."와 같은 메모리 크기 약어를 허용하므로 오타 안전합니다.
Leo의 답변을 기반으로 추가
최대 단위를 메가로 바꾸려면 $units = explode(' ', ' 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];
}