PHP count total files in directory AND subdirectory function

count, directory, file, php

Solution

For the fun of it I've whipped this together:

class FileFinder
{
    private $onFound;

    private function __construct($path, $onFound, $maxDepth)
    {
        // onFound gets called at every file found
        $this->onFound = $onFound;
        // start iterating immediately
        $this->iterate($path, $maxDepth);
    }

    private function iterate($path, $maxDepth)
    {
        $d = opendir($path);
        while ($e = readdir($d)) {
            // skip the special folders
            if ($e == '.' || $e == '..') { continue; }
            $absPath = "$path/$e";
            if (is_dir($absPath)) {
                // check $maxDepth first before entering next recursion
                if ($maxDepth != 0) {
                    // reduce maximum depth for next iteration
                    $this->iterate($absPath, $maxDepth - 1);
                }
            } else {
                // regular file found, call the found handler
                call_user_func_array($this->onFound, array($absPath));
            }
        }
        closedir($d);
    }

    // helper function to instantiate one finder object
    // return value is not very important though, because all methods are private
    public static function find($path, $onFound, $maxDepth = 0)
    {
        return new self($path, $onFound, $maxDepth);
    }
}

// start finding files (maximum depth is one folder down) 
$count = $bytes = 0;
FileFinder::find('.', function($file) use (&$count, &$bytes) {
    // the closure updates count and bytes so far
    ++$count;
    $bytes += filesize($file);
}, 1);

echo "Nr files: $count; bytes used: $bytes\n";

You pass the base path, found handler and maximum directory depth (-1 to disable). The found handler is a function you define outside, it gets passed the path name relative from the path given in the `find()` function.

Hope it makes sense and helps you :)

Problem

I need to get a total count of JPG files within a specified directory, including ALL it's subdirectories. No sub-sub directories. Structure looks like this : ``` dir1/ 2 files subdir 1/ 8 files ``` total dir1 = 10 files ``` dir2/ 5 files subdir 1/ 2 files subdir 2/ 8 files ``` total dir2 = 15 files I have this function, which doesn't work fine as it only counts files in the last subdirectory, and total is 2x more than the actual amount of files. (will output 80 if I have 40 files in the last subdir) ``` public function count_files($path) { global $file_count; $file_count = 0; $dir = opendir($path); if (!$dir) return -1; while ($file = readdir($dir)) : if ($file == '.' || $file == '..') continue; if (is_dir($path . $file)) : $file_count += $this->count_files($path . "/" . $file); else : $file_count++; endif; endwhile; closedir($dir); return $file_count; } ```

Original source