web-dev-qa-db-fra.com

taille de fichier lisible par l'homme

function humanFileSize($size)
{
    if ($size >= 1073741824) {
      $fileSize = round($size / 1024 / 1024 / 1024,1) . 'GB';
    } elseif ($size >= 1048576) {
        $fileSize = round($size / 1024 / 1024,1) . 'MB';
    } elseif($size >= 1024) {
        $fileSize = round($size / 1024,1) . 'KB';
    } else {
        $fileSize = $size . ' bytes';
    }
    return $fileSize;
}

... fonctionne très bien, sauf que: Je ne peux pas choisir manuellement le format d'affichage, disons que je veux afficher en Mo uniquement quelle que soit la taille du fichier. Actuellement, si elle se situe dans la plage de Go, elle n’affichera qu’en Go.

Aussi, comment limiter le nombre décimal à 2?

26
3zzy

Essayez quelque chose comme ça:

function humanFileSize($size,$unit="") {
  if( (!$unit && $size >= 1<<30) || $unit == "GB")
    return number_format($size/(1<<30),2)."GB";
  if( (!$unit && $size >= 1<<20) || $unit == "MB")
    return number_format($size/(1<<20),2)."MB";
  if( (!$unit && $size >= 1<<10) || $unit == "KB")
    return number_format($size/(1<<10),2)."KB";
  return number_format($size)." bytes";
}
46

Il y a un bon exemple de Jeffrey Sambells :

function human_filesize($bytes, $dec = 2) 
{
    $size   = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
    $factor = floor((strlen($bytes) - 1) / 3);

    return sprintf("%.{$dec}f", $bytes / pow(1024, $factor)) . @$size[$factor];
}

print human_filesize(filesize('example.Zip'));
34
Vaidas

J'utilise cette méthode:

function byteConvert($bytes)
{
    if ($bytes == 0)
        return "0.00 B";

    $s = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
    $e = floor(log($bytes, 1024));

    return round($bytes/pow(1024, $e), 2).$s[$e];
}

fonctionne très bien dans o (1).

11
Roey

Pour développer la réponse de Vaidas, voici comment procéder pour prendre en compte les nouvelles normes IEC:

function human_readable_bytes($bytes, $decimals = 2, $system = 'binary')
{
    $mod = ($system === 'binary') ? 1024 : 1000;

    $units = array(
        'binary' => array(
            'B',
            'KiB',
            'MiB',
            'GiB',
            'TiB',
            'PiB',
            'EiB',
            'ZiB',
            'YiB',
        ),
        'metric' => array(
            'B',
            'kB',
            'MB',
            'GB',
            'TB',
            'PB',
            'EB',
            'ZB',
            'YB',
        ),
    );

    $factor = floor((strlen($bytes) - 1) / 3);

    return sprintf("%.{$decimals}f%s", $bytes / pow($mod, $factor), $units[$system][$factor]);
}

Techniquement, conformément aux spécifications des périphériques de stockage, vous devez utiliser le système métrique par défaut (c’est pourquoi Google converter indique que kB -> Mo est mod 1000 et non 1024).

3
Krzysztof Karski
function getHumanReadableSize($size, $unit = null, $decemals = 2) {
    $byteUnits = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    if (!is_null($unit) && !in_array($unit, $byteUnits)) {
        $unit = null;
    }
    $extent = 1;
    foreach ($byteUnits as $rank) {
        if ((is_null($unit) && ($size < $extent <<= 10)) || ($rank == $unit)) {
            break;
        }
    }
    return number_format($size / ($extent >> 10), $decemals) . $rank;
}

Si la version php inférieure à 5.4 utilise $byteUnits = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');

Je voulais une fonction qui renvoyait la taille du fichier comme Windows et, étonnamment, je n’en ai trouvé aucun. Pire encore, certains ici et ailleurs sont cassés en ce qu'ils supposent 1KB = 1000B.

Alors j'ai codé un! Plus deux fonctions d'assistance. Les voici:

// Returns a size in a human-readable form from a byte count.
function humanSize($bytes)
{
    if ($bytes < 1024) return "$bytes Bytes";

    $units = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

    foreach ($units as $i => $unit)
    {
        // The reason for this threshold is to avoid e.g., "1000 KB",
        // instead jumping from e.g., "999 KB" to "0.97 MB".
        $multiplier = pow(1024, $i + 1);
        $threshold = $multiplier * 1000;

        if ($bytes < $threshold)
        {
            $size = formatToMinimumDigits($bytes / $multiplier, false);
            return "$size $unit";
        }
    }
}

// Efficiently calculates how many digits the integer portion of a number has.
function digits($number)
{
    // Yes, I could convert to string and count the characters,
    // but this is faster and cooler.
    $log = log10($number);
    if ($log < 0) return 1;
    return floor($log) + 1;
}

// Formats a number to a minimum amount of digits.
// In other words, makes sure that a number has at least $digits on it, even if
// that means introducing redundant decimal zeroes at the end, or rounding the
// ones present exceeding the $digits count when combined with the integers.
// For example:
//     formatToMinimumDigits(10)           // 10.0
//     formatToMinimumDigits(1.1)          // 1.10
//     formatToMinimumDigits(12.34)        // 12.3
//     formatToMinimumDigits(1.234)        // 1.23
//     formatToMinimumDigits(1.203)        // 1.20
//     formatToMinimumDigits(123.4)        // 123
//     formatToMinimumDigits(100)          // 100
//     formatToMinimumDigits(1000)         // 1000
//     formatToMinimumDigits(1)            // 1.00
//     formatToMinimumDigits(1.002)        // 1.00
//     formatToMinimumDigits(1.005)        // 1.01
//     formatToMinimumDigits(1.005, false) // 1.00
// This is primarily useful for generating human-friendly numbers.
function formatToMinimumDigits($value, $round = true, $digits = 3)
{
    $integers = floor($value);

    $decimalsNeeded = $digits - digits($integers);

    if ($decimalsNeeded < 1)
    {
        return $integers;
    }
    else
    {
        if ($round)
        {
            // This relies on implicit type casting of float to string.
            $parts = explode('.', round($value, $decimalsNeeded));
            // We re-declare the integers because they may change
            // after we round the number.
            $integers = $parts[0];
        }
        else
        {
            // Again, implicit type cast to string.
            $parts = explode('.', $value);
        }

        // And because of the implicit type cast, we must guard against
        // 1.00 becoming 1, thus not exploding the second half of it.
        $decimals = isset($parts[1]) ? $parts[1] : '0';
        $joined = "$integers.$decimals".str_repeat('0', $digits);
        return substr($joined, 0, $digits + 1);
    }
}

L'utilisation est aussi simple que humanSize(123456789).

1
Camilo Martin

Une méthode assez courte de 3 lignes que j'utilise (1024 = 1 Ko) et prend en charge de KB à YB est la suivante:

<?php 

/**
 * Converts a long string of bytes into a readable format e.g KB, MB, GB, TB, YB
 * 
 * @param {Int} num The number of bytes.
 */
function readableBytes($bytes) {
    $i = floor(log($bytes) / log(1024));

    $sizes = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');

    return sprintf('%.02F', $bytes / pow(1024, $i)) * 1 . ' ' . $sizes[$i];
}

// "1000 B"
echo readableBytes(1000);

// "9.42 MB"
echo readableBytes(9874321);

// "9.31 GB"
// The number of bytes as a string is accepted as well
echo readableBytes("10000000000");

// "648.37 TB"
echo readableBytes(712893712304234);

// "5.52 PB"
echo readableBytes(6212893712323224);

Plus d'infos sur ces méthodes sur cet article .

1
Carlos Delgado

Voici une fonction de travail gérant jusqu'à Yottabyte:

function DisplayFileSize($size, $unit = false, $precision = 2){

$b = $size;
$kb = round($size / 1024, $precision);
$mb = round($kb / 1024, $precision);
$gb = round($mb / 1024, $precision);
$tb = round($gb / 1024, $precision);
$pb = round($tb / 1024, $precision);
$eb = round($pb / 1024, $precision);
$zb = round($eb / 1024, $precision);
$yb = round($zb / 1024, $precision);

if((!$unit && floor($kb) == 0) || $unit == "b") {
    return array("value" => FormatNumber($b), "unit" => "bytes");
} else if((!$unit && floor($mb) == 0) || $unit == "kb") {
    return array("value" => FormatNumber($kb, 2), "unit" => "Kb");
} else if((!$unit && floor($gb) == 0) || $unit == "mb") {
    return array("value" => FormatNumber($mb, 2), "unit" => "Mb");
 } else if((!$unit && floor($tb) == 0) || $unit == "gb") {
     return array("value" => FormatNumber($gb, 2), "unit" => "Gb");
 } else if((!$unit && floor($pb) == 0) || $unit == "tb") {
     return array("value" => FormatNumber($tb, 2), "unit" => "Tb");
 } else if((!$unit && floor($eb) == 0) || $unit == "pb") {
    return array("value" => FormatNumber($pb, 2), "unit" => "Pb");
 } else if((!$unit && floor($zb) == 0) || $unit == "eb") {
     return array("value" => FormatNumber($eb, 2), "unit" => "Eb");
 } else if((!$unit && floor($yb) == 0) || $unit == "zb") {
     return array("value" => FormatNumber($zb, 2), "unit" => "Zb");
} else {
    return array("value" => FormatNumber($yb, 2), "unit" => "Yb");
}

}

0
Matbe81

Vous pouvez modifier votre fonction pour satisfaire à la fois votre besoin de forcer une unité si elle vous est donnée et d’ajuster la précision. 

function humanFileSize($size, $precision = 1, $show = "")
{
    $b = $size;
    $kb = round($size / 1024, $precision);
    $mb = round($kb / 1024, $precision);
    $gb = round($mb / 1024, $precision);

    if($kb == 0 || $show == "B") {
        return $b . " bytes";
    } else if($mb == 0 || $show == "KB") {
        return $kb . "KB";
    } else if($gb == 0 || $show == "MB") {
        return $mb . "MB";
    } else {
        return $gb . "GB";
    }
}

//Test with different values
echo humanFileSize(1038) . "<br />";    
echo humanFileSize(103053, 0) . "<br />";
echo humanFileSize(103053) . "<br />";
echo humanFileSize(1030544553) . "<br />";
echo humanFileSize(1030534053405, 2, "GB") . "<br />";  ;
0
automaticoo