php - mejor - que es mas un gb o un mb en internet
Formato de bytes a kilobytes, megabytes, gigabytes (22)
Aquí hay una implementación simplificada de la función 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;
}
}
Escenario: el tamaño de varios archivos se almacena en una base de datos como bytes. ¿Cuál es la mejor forma de formatear esta información de tamaño a kilobytes, megabytes y gigabytes? Por ejemplo, tengo un MP3 que Ubuntu muestra como "5.2 MB (5445632 bytes)". ¿Cómo podría mostrar esto en una página web como "5.2 MB" Y tener archivos de menos de un megabyte como KB y archivos de un gigabyte y más como GB?
Desarrollé mi propia función que convierte el tamaño de la memoria humana legible a diferentes tamaños.
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
Esta función acepta cualquier abreviatura de tamaño de memoria como "Megabyte, MB, Mb, mb, m, kilobyte, K, KB, b, Terabyte, T ...." por lo que es seguro contra errores tipográficos.
Es un poco tarde, pero a continuación se incluye una versión ligeramente más rápida de la respuesta aceptada:
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];
}
Es más eficiente, debido a la realización de una única operación de log-2 en lugar de dos operaciones de log-e.
Sin embargo, en realidad es más rápido hacer la solución más obvia a continuación:
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];
}
Esto se debe a que el índice se calcula al mismo tiempo que el valor del número de bytes en la unidad apropiada. Esto redujo el tiempo de ejecución en aproximadamente un 35% (un aumento de velocidad del 55%).
Esta es Kohana''s implementación Kohana''s , podrías usarla:
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]);
}
Esta es la implementación de Chris Jester-Young, la más limpia que he visto, combinada con php.net y un argumento de precisión.
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
Función extremadamente simple para obtener el tamaño de archivo humano.
Fuente original: http://php.net/manual/de/function.filesize.php#106569
Copiar / pegar código:
<?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];
}
?>
Función simple
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
Logré con la siguiente función
function format_size($size) {
$mod = 1024;
$units = explode('' '',''B KB MB GB TB PB'');
for ($i = 0; $size > $mod; $i++) {
$size /= $mod;
}
return round($size, 2) . '' '' . $units[$i];
}
Mi acercamiento
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];
}
}
No sé por qué deberías hacerlo tan complicado como los demás.
El siguiente código es mucho más fácil de entender y aproximadamente un 25% más rápido que las otras soluciones que usan la función de registro (llamada función 20 Mio. veces con diferentes parámetros)
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];
}
Otra implementación condensada que puede traducirse a la base 1024 (binario) o base 1000 (decimal) y también funciona con números increíblemente grandes, por lo tanto, del uso de la biblioteca 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'';
}
Pensé que agregaría un mallado de dos códigos de remitentes (usando el código de John Himmelman, que está en este hilo y usando el código de Eugene Kuzmenko ) que estoy usando.
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
}
}
Esto usa el código de Eugene para formatear el $value
en bytes (guardo mis datos en MB, entonces convierte mis datos: 10485760 MB
en 10995116277760
) - luego usa el código de John para convertirlo en el valor de visualización adecuado ( 10995116277760
en 10 TB
) .
Esto me ha resultado muy útil, ¡así que gracias a los dos remitentes!
Pseudocódigo:
$base = log($size) / log(1024);
$suffix = array("", "k", "M", "G", "T")[floor($base)];
return pow(1024, $base - floor($base)) . $suffix;
Sé que tal vez sea un poco tarde para responder esta pregunta, pero más datos no matarán a nadie. Aquí hay una función muy rápida:
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'';
}
EDITAR: Actualicé mi publicación para incluir la solución propuesta por 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'';
}
Simplemente divídalo por 1024 para kb, 1024 ^ 2 para mb y 1024 ^ 3 para GB. Tan sencillo como eso.
Solo mi alternativa, corta y limpia:
/**
* @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];
}
o, más estúpido y eficiente:
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";
}
prueba esto ;)
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);
usa esta función si quieres un código corto
$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
function byte_format($size) {
$bytes = array( '' KB'', '' MB'', '' GB'', '' TB'' );
foreach ($bytes as $val) {
if (1024 <= $size) {
$size = $size / 1024;
continue;
}
break;
}
return round( $size, 1 ) . $val;
}
function changeType($size, $type, $end){
$arr = [''B'', ''KB'', ''MB'', ''GB'', ''TB''];
$tSayi = array_search($type, $arr);
$eSayi = array_search($end, $arr);
$pow = $eSayi - $tSayi;
return $size * pow(1024 * $pow) . '' '' . $end;
}
echo changeType(500, ''B'', ''KB'');
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];
}
Solo llame a la función
echo convertToReadableSize(1024); // Outputs ''1KB''
echo convertToReadableSize(1024 * 1024); // Outputs ''1MB''
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];
}
(Tomado de php.net , hay muchos otros ejemplos allí, pero este me gusta más :-)