Scénario: la taille des différents fichiers est stockée dans une base de données sous forme d'octets. Quelle est la meilleure façon de formater ces informations de taille en kilo-octets, mégaoctets et gigaoctets? Par exemple, j'ai un MP3 qu'Ubuntu affiche comme "5,2 Mo (5445632 octets)". Comment est-ce que j'afficherais ceci sur une page Web en tant que «5,2 Mo» ET que les fichiers de moins d'un mégaoctet s'affichent en Ko et les fichiers d'un gigaoctet et plus s'affichent en Go?
187
Réponses:
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]; }
(Tiré de php.net , il y a beaucoup d'autres exemples, mais j'aime mieux celui-ci :-)
la source
$bytes /= (1 << (10 * $pow))
ou similaire, je pourrais mieux l'aimer. :-PKiB
,MiB
,GiB
etTiB
puisque vous divisez par1024
. Si vous divisez par1000
elle, ce serait sans lei
.Uncomment one of the following alternatives
était quelque chose que je n'ai pas remarqué pendant 5 minutes ...C'est l'implémentation de Chris Jester-Young, la plus propre que j'aie jamais vue, combinée avec php.net et un argument de précision.
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
la source
$suffixes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
je veux un disque dur de Yottabyte! :-PformatBytes(259748192, 3)
renvoie259748192 MB
ce qui n'est pas correctPseudocode:
$base = log($size) / log(1024); $suffix = array("", "k", "M", "G", "T")[floor($base)]; return pow(1024, $base - floor($base)) . $suffix;
la source
Divisez-le simplement par 1024 pour kb, 1024 ^ 2 pour mb et 1024 ^ 3 pour Go. Aussi simple que cela.
la source
C'est l' implémentation de Kohana , vous pouvez l'utiliser:
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]); }
la source
$force_unit
et$si
semblent faire la même chose. Vous pouvez également transmettre n'importe quelle chaîne contenant un "i" à$force_unit
, car ils testent la position. Le formatage décimal est également exagéré.Juste mon alternative, courte et propre:
/** * @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]; }
ou, plus stupide et efficace:
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"; }
la source
utilisez cette fonction si vous voulez un code court
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
la source
Je sais qu'il est peut-être un peu tard pour répondre à cette question, mais plus de données ne tueront personne. Voici une fonction très rapide:
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'; }
EDIT: J'ai mis à jour mon message pour inclure le correctif proposé par 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'; }
la source
Fonction 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
la source
Solution flexible:
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"
la source
J'ai réussi avec la fonction suivante,
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]; }
la source
Mon approche
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]; } }
la source
Je ne sais pas pourquoi vous devriez le rendre aussi compliqué que les autres.
Le code suivant est beaucoup plus simple à comprendre et environ 25% plus rapide que les autres solutions qui utilisent la fonction log (appelée la fonction 20 millions de fois avec des paramètres différents)
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]; }
la source
J'ai fait cela en convertissant toutes les entrées en octets et en les convertissant ainsi en toute sortie nécessaire. De plus, j'ai utilisé une fonction auxiliaire pour obtenir la base 1000 ou 1024, mais je l'ai laissée fléchir pour décider d'utiliser 1024 sur le type populaire (sans «i», comme MB au lieu de 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; }
la source
essaye ça ;)
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);
la source
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');
la source
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]; }
Appelez simplement la fonction
echo convertToReadableSize(1024); // Outputs '1KB' echo convertToReadableSize(1024 * 1024); // Outputs '1MB'
la source
Ce travail avec le dernier 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]; }
la source
Bien qu'un peu obsolète, cette bibliothèque propose une API de conversion testée et robuste:
https://github.com/gabrielelana/byte-units
Une fois installé:
\ByteUnits\Binary::bytes(1024)->format(); // Output: "1.00KiB"
Et pour convertir dans l'autre sens:
\ByteUnits\Binary::parse('1KiB')->numberOfBytes(); // Output: "1024"
Au-delà de la conversion de base, il propose des méthodes d'addition, de soustraction, de comparaison, etc.
Je ne suis aucunement affilié à cette bibliothèque.
la source
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; }
la source
Voici une implémentation simplifiée de la fonction 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; } }
la source
Il est un peu tard mais une version légèrement plus rapide de la réponse acceptée est ci-dessous:
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]; }
C'est plus efficace, car il effectue une seule opération log-2 au lieu de deux opérations log-e.
Cependant, il est en fait plus rapide de faire la solution la plus évidente ci-dessous:
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]; }
En effet, comme l'index est calculé en même temps que la valeur du nombre d'octets dans l'unité appropriée. Cela a réduit le temps d'exécution d'environ 35% (une augmentation de vitesse de 55%).
la source
Une autre implémentation condensée qui peut se traduire en base 1024 (binaire) ou en base 1000 (décimal) et fonctionne également avec des nombres incroyablement grands d'où l'utilisation de la bibliothèque 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'; }
la source
bcpow()
lancera une exception TypeError si$base
et$i
ne sont pas des valeurs de chaîne. Testé sur PHP version 7.0.11.J'ai pensé que j'ajouterais un maillage de code de deux soumetteurs (en utilisant le code de John Himmelman, qui est dans ce fil, et en utilisant le code d' Eugene Kuzmenko ) que j'utilise.
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 } }
Cela utilise le code d'Eugene pour formater le
$value
en octets (je garde mes données en Mo, donc il convertit mes données:10485760 MB
en10995116277760
) - il utilise ensuite le code de John pour le convertir en la valeur d'affichage appropriée (10995116277760
en10 TB
).J'ai trouvé cela vraiment utile - donc mes remerciements aux deux soumissionnaires!
la source
Fonction extrêmement simple pour obtenir la taille du fichier humain.
Source originale: http://php.net/manual/de/function.filesize.php#106569
Copier / coller du code:
<?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]; } ?>
la source
J'ai développé ma propre fonction qui convertit la taille de la mémoire lisible par l'homme en différentes tailles.
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
Cette fonction accepte toutes les abréviations de taille de mémoire telles que "Mégaoctet, Mo, Mb, mb, m, kilo-octet, K, KB, b, Téraoctet, T ....".
la source
Basez-vous sur la réponse de Leo , ajoutez
Si vous voulez que l'unité maximale soit Mega, passez à
$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]; }
la source