Format des octets en kilo-octets, mégaoctets, gigaoctets
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 cette information de taille en kilo-octets, mégaoctets et gigaoctets? Par exemple, j'ai un MP3 Qu'Ubuntu affiche comme "5.2 MB (5445632 octets)". Comment afficherais-je cela sur une page web en tant que "5.2 MB" et avoir des fichiers de moins d'un mégaoctet en Ko et des fichiers d'un gigaoctet et plus en Go?
23 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 là-bas, mais j'aime celui-ci le mieux: -)
C'est la mise en œuvre de Chris Jester-Young, la plus propre que j'ai 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
Pseudo-code:
$base = log($size) / log(1024);
$suffix = array("", "k", "M", "G", "T")[floor($base)];
return pow(1024, $base - floor($base)) . $suffix;
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]);
}
Il suffit de le diviser par 1024 pour kb, 1024^2 pour mb et 1024^3 Pour GB. Aussi simple que cela.
Utilisez cette fonction si vous voulez un code Court
$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
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";
}
Je sais qu'il est peut-être un peu tard pour répondre à cette question mais, plus de données ne va pas tuer quelqu'un. 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 post 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';
}
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
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];
}
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];
}
}
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');
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 Mio. avec différents paramètres)
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];
}
Essayez ceci ;)
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 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;
}
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;
}
}
C'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, en raison de l'exécution d'une seule opération log-2 au lieu de deux opérations log-E.
Il est en fait plus rapide de faire la solution la plus évidente ci-dessous, cependant:
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];
}
C'est parce que l'index est calculé en même temps que la valeur du nombre d'octets dans l'unité appropriée. Cela réduit le temps d'exécution d'environ 35% (une augmentation de la vitesse de 55%).
Une autre implémentation condensée qui peut se traduire en base 1024 (binaire) ou en base 1000 (décimale) 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';
}
J'ai pensé que j'ajouterais un maillage de code de deux submitters (en utilisant le code de John Himmelman, qui est dans ce fil, et en utilisant le code deEugene 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
en 10995116277760
) - il utilise ensuite le code de John pour le convertir en la valeur d'affichage appropriée (10995116277760
en 10 TB
).
J'ai trouvé cela vraiment utile-donc mes remerciements aux deux auteurs!
Fonction extrêmement simple pour obtenir la taille du fichier humain.
Source Originale: http://php.net/manual/de/function.filesize.php#106569
Copier/coller le 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];
}
?>
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 toute abréviation de taille de mémoire comme " mégaoctet, MB, Mb, mb, m, kilooctet, K, KB, b, téraoctet, T...."donc, c'est de la faute de frappe coffre-fort.
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'
Base sur la réponse de Leo , Ajouter
- Support Pour négatif
- Soutien 0
Si vous voulez que l'unité max soit méga, 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];
}