wrichards0
wrichards0

Reputation: 187

Recursive function to get filesize in PHP

I am working on a PHP function that will scan a given folder and return the total size of all the files in the folder. My issue is that, even though it works for files stored in the root of that folder, it doesn't work for files in any subfolder. My code is:

function get_total_size($system)
{
    $size = 0;
    $path = scandir($system);
    unset($path[0], $path[1]);
    foreach($path as $file)
    {
        if(is_dir($file))
        {
            get_total_size("{$system}/{$file}");
        }
        else
        {
            $size = $size + filesize("{$system}/{$file}");
        }
    }
    $size = $size / 1024;
    return number_format($size, 2, ".", ",");
}    

I'm unsetting the 0th and 1st elements of the array since these are the dot and the double dot to go up a directory. Any help would be greatly appreciated

Upvotes: 1

Views: 1318

Answers (4)

Nahid Bin Azhar
Nahid Bin Azhar

Reputation: 763

You may try this procedure. When you check this file is_dir then you have to count the file size also. And when you check is_dir you have to concat it with root directory otherwise it show an error.

function get_total_size($system)
{
    $size = 0;
    $path = scandir($system);
    unset($path[0], $path[1]);
    foreach($path as $file)
    {
        if(is_dir($system.'/'.$file))
        {
            $size+=get_total_size("{$system}/{$file}");
        }
        else
        {
            $size = $size + filesize("{$system}/{$file}");
        }
    }
    $size = $size / 1024;
    return number_format($size, 2, ".", ",");
}  

I think it will work fine

Happy coding :)

Upvotes: 1

Professor Abronsius
Professor Abronsius

Reputation: 33823

The recursiveIterator family of classes could be of use to you.

function filesize_callback( $obj, &$total ){
    foreach( $obj as $file => $info ){
        if( $obj->isFile() ) {
            echo 'path: '.$obj->getPath().' filename: '.$obj->getFilename().' filesize: '.filesize( $info->getPathName() ).BR;
            $total+=filesize( $info->getPathName() );
        } else filesize_callback( $info,&$total );
    }
}
$total=0;
$folder='C:\temp';
$iterator=new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $folder, RecursiveDirectoryIterator::KEY_AS_PATHNAME ), RecursiveIteratorIterator::CHILD_FIRST );
call_user_func( 'filesize_callback', $iterator, &$total );

echo BR.'Grand-Total: '.$total.BR;

Upvotes: 0

Chetan Ameta
Chetan Ameta

Reputation: 7896

you can use recursive directory iterator for the same. Have a look on below solution:

<?php
$total_size = 0;
$di = new RecursiveDirectoryIterator('/directory/path');
foreach (new RecursiveIteratorIterator($di) as $filename => $file) {
   if($file->isFile()) {
        echo $filename . ' - ' . $file->getSize() . ' bytes <br/>';
        $total_size += $file->getSize();
    }
}

echo $total_size; //in bytes
?>

Upvotes: 1

Jerodev
Jerodev

Reputation: 33216

You forgot to count the size of the subfolders. you have to add it to the $size variable.

function get_total_size($system)
{
    $size = 0;
    $path = scandir($system);
    unset($path[0], $path[1]);
    foreach($path as $file)
    {
        if(is_dir($file))
        {
            $size += get_total_size("{$system}/{$file}"); // <--- HERE
        }
        else
        {
            $size = $size + filesize("{$system}/{$file}");
        }
    }
    return $size;
}    

This might however give a problem because you are using the number_format function. I would not do this and add the formatting after receiving the result of the get_total_size function.

Upvotes: 1

Related Questions