tags:

views:

56

answers:

1

I'm writing a simple file-caching engine in PHP that needs to be able to see how big a directory is. What I'm looking for is the equivalent of Unix's du command to simply print the total filesize of a directory. I can write it myself, but if somebody else already figured out all the issues of recursing and handling symlinks and so on, that would be great.

+4  A: 

Something along the lines of this:

$iterator = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator(
                    '/path/to/a/folder'));

The iterator will let you you recursively iterate over the designated folder and subfolders and returns SplFileInfo objects. The default option is to just return the leaves, e.g. files, but not directory items, so you can do:

$size = 0;
foreach($iterator as $file) {
    $size += filesize($file->getRealPath());
}
echo $size;

By using getRealPath() on the file, we make sure all symlinks are expanded. Not sure if this would take symlinks to directories into account though. I just don't know if they are considered leaves then.

Anyway, here is a functional approach using a lambda:

echo array_reduce(iterator_to_array($iterator), function($size, $file) {
    $size += filesize($file->getRealPath());
    return $size;
});

And another approach using a custom iterator:

class FileSizeIterator extends RecursiveIteratorIterator
{
    public function current() {
        return filesize($this->getInnerIterator()->current()->getRealpath());
    }
}

echo array_sum(iterator_to_array(new FileSizeIterator(
        new RecursiveDirectoryIterator('/path/to/a/folder'))));

You might want to compare the result to du to make sure it's correct.

Gordon
How does this handle symlinks?
erjiang
@mazin I am not sure how PHP treats symlinks to directories and if it will traverse into them. For symlinks to files, you getRealPath should be sufficient. Just try any of the above and see if it matches the results of `du`
Gordon