135 votes

Conversion de la taille des fichiers PHP en MB/KB

Comment puis-je convertir la sortie de la fonction PHP filesize() dans un format agréable avec des mégaoctets, des kilooctets, etc.

comme :

  • si la taille est inférieure à 1 MB, afficher la taille en KB
  • si la taille est comprise entre 1 Mo et 1 Go, affichez-la en Mo.
  • si elle est plus grande - en GB

1 votes

302voto

Adnan Points 9393

En voici un exemple :

<?php
// Snippet from PHP Share: http://www.phpshare.org

    function formatSizeUnits($bytes)
    {
        if ($bytes >= 1073741824)
        {
            $bytes = number_format($bytes / 1073741824, 2) . ' GB';
        }
        elseif ($bytes >= 1048576)
        {
            $bytes = number_format($bytes / 1048576, 2) . ' MB';
        }
        elseif ($bytes >= 1024)
        {
            $bytes = number_format($bytes / 1024, 2) . ' KB';
        }
        elseif ($bytes > 1)
        {
            $bytes = $bytes . ' bytes';
        }
        elseif ($bytes == 1)
        {
            $bytes = $bytes . ' byte';
        }
        else
        {
            $bytes = '0 bytes';
        }

        return $bytes;
}
?>

5 votes

Cette réponse est plus efficace que les autres ci-dessous. Elle évite d'utiliser la fonction logarithmique ou les déclarations de divisions successives pour identifier l'unité.

1 votes

C'est une solution brillante, merci pour cette fonction géniale - exactement ce que je recherchais.

1 votes

Magnifique. Merci.

68voto

PiTheNumber Points 8264

Encore plus belle est cette version que j'ai créée à partir de un plugin J'ai trouvé :

function filesize_formatted($path)
{
    $size = filesize($path);
    $units = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
    $power = $size > 0 ? floor(log($size, 1024)) : 0;
    return number_format($size / pow(1024, $power), 2, '.', ',') . ' ' . $units[$power];
}

Note de filesize() doc

Parce que le type d'entier de PHP est signé et que de nombreuses plateformes utilisent des entiers 32bit. certaines fonctions du système de fichiers peuvent retourner des résultats inattendus pour des les fichiers dont la taille est supérieure à 2GB

1 votes

Pourquoi est-il "plus beau" ? Elle fait presque la même chose que ma version, sauf qu'elle renvoie une taille erronée pour les fichiers de plus de 2 Go (de plus, le PO n'a jamais demandé les unités de puissance restantes).

6 votes

@AlixAxel C'est plus joli, car il fait la moitié de la taille et reste facile à lire. Je parie aussi que c'est plus rapide. Mais bon, ce n'est pas personnel. Je n'y ai pas pensé moi-même. Ta version est cool aussi ! Je l'ai upvoted ;)

1 votes

Adnan a posté la réponse la plus verbeuse, mais aussi la plus efficace. L'utilisation de la fonction logarithmique pour identifier les unités est beaucoup plus lente que l'utilisation de simples inégalités. Même l'utilisation d'instructions de division successives dans une boucle est beaucoup plus rapide que l'utilisation de la fonction logarithmique.

43voto

Alix Axel Points 63455

Une approche plus propre :

function Size($path)
{
    $bytes = sprintf('%u', filesize($path));

    if ($bytes > 0)
    {
        $unit = intval(log($bytes, 1024));
        $units = array('B', 'KB', 'MB', 'GB');

        if (array_key_exists($unit, $units) === true)
        {
            return sprintf('%d %s', $bytes / pow(1024, $unit), $units[$unit]);
        }
    }

    return $bytes;
}

0 votes

Cela semble plus propre mais l'utilisation du log pour identifier les unités est beaucoup plus coûteuse que l'utilisation de quelques inégalités simples.

0 votes

@AliGangji : C'est vrai, entre 0,1 % et 42 % plus coûteux pour être précis (en fonction de ce qui if condition $bytes tombe dedans).

0 votes

@AliGangji : Pour développer mon dernier commentaire, il semble que pour les valeurs <= 1023 octets, l'approche log est en moyenne ~40% plus lente. mais pour 1024 et plus, j'obtiens des moyennes cohérentes de l'ordre de 0,1%. Intéressant !

15voto

Teffi Points 157

Je pense que c'est une meilleure approche. Simple et directe.

public function sizeFilter( $bytes )
{
    $label = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB' );
    for( $i = 0; $bytes >= 1024 && $i < ( count( $label ) -1 ); $bytes /= 1024, $i++ );
    return( round( $bytes, 2 ) . " " . $label[$i] );
}

8voto

Jens-André Koch Points 3506

Ceci est basé sur l'excellente réponse de @adnan.

Changements :

  • ajout d'un appel interne filesize()
  • retour anticipé
  • sauvegarde d'une concaténation sur 1 octet

Et vous pouvez toujours retirer l'appel filesize() de la fonction, afin d'obtenir une fonction de formatage d'octets pure. Mais cela fonctionne sur un fichier.


/**
 * Formats filesize in human readable way.
 *
 * @param file $file
 * @return string Formatted Filesize, e.g. "113.24 MB".
 */
function filesize_formatted($file)
{
    $bytes = filesize($file);

    if ($bytes >= 1073741824) {
        return number_format($bytes / 1073741824, 2) . ' GB';
    } elseif ($bytes >= 1048576) {
        return number_format($bytes / 1048576, 2) . ' MB';
    } elseif ($bytes >= 1024) {
        return number_format($bytes / 1024, 2) . ' KB';
    } elseif ($bytes > 1) {
        return $bytes . ' bytes';
    } elseif ($bytes == 1) {
        return '1 byte';
    } else {
        return '0 bytes';
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X