PHP print_filesize function

Recently I've been on a drive to eliminate dependencies from my code and other areas, such as blog posts. For those who create content for the Web, a reasonably common task is to provide links to files that can be downloaded. It is considered good practice to include an indication of a file's size; for example: favicon.ico (3 KB).

As I was about to hard-code a file's size into a blog post recently, I thought to myself: Will I remember to update this if the file's size changes? More importantly, should I be required to remember such things? The answer, of course, is no. I set about writing a function that would allow the file's size to be displayed dynamically.

/**
 * echoes nicely formatted filesize
 * @param string $filename
 * @param string $before
 * @param string $after
 */
function print_filesize($filename, $before = ' <span class="filesize">(', $after = ')</span>')
{
    if (file_exists($filename))
    {
        $size = filesize($filename);
        $unit = 'B';

        if (intval($size/(1024*1024*1024)))
        {
            $size = number_format(($size/(1024*1024*1024)), 1);
            $unit = 'GB';
        }
        elseif (intval($size/(1024*1024)))
        {
            $size = number_format(($size/(1024*1024)), 1);
            $unit = 'MB';
        }
        elseif (intval($size/1024))
        {
            $size = number_format(($size/1024), 1);
            $unit = 'KB';
        }

        $approx = $unit == 'B' ? '' : '≈' ;

        echo "{$before}{$approx}{$size} {$unit}{$after}";
    }
}

Example usage:

<a href="favicon.ico">favicon.ico</a><?php print_filesize('favicon.ico'); ?>

This gives: favicon.ico (≈1.1 kB). By default, the function wraps the file's size in a span element with class="filesize", to provide a hook for styling if required.

Comments

Nice. I tell you what though, you missed a golden opportunity to write a completely unnecessary recursive function.

DB

@DB I only recently discovered that such a thing exists. I agree, it would have been cool (but as you say, unnecessary) to use one here. My brother pointed out that this function could be written as a shell script in one simple line. What can I say? PHP ain't exactly renowned for its concision.

What about using a loop to determine the size?

function print_filesize($filename, $before = ' (', $after = ')'){
    $units = array('B', 'KB', 'MB', 'GB', 'TB');
    $index = 0;
    if (file_exists($filename)){
        $size = filesize($filename);
        while($size > 1024){
            $size /= 1024;
            ++$index;
        }

        $approx = '';
        if($index > 0){
            $size = number_format($size, 1);
            $approx = '~';
        }
        $unit = $units[$index];
        echo "{$before}{$approx}{$size} {$unit}{$after}";
    }
    echo '';
}
banal

@banal That's a much nicer solution. :)

Respond