wiecman
wiecman

Reputation: 103

Count files in each folder

I tried to count files in each subfolder. For example

first subfolder : 4 files
second subfolder : 6 files ...

Now my function count files in directory which I select in array:

if (!is_dir($subentry) && $gallery_dir[0]) {

How to can I count and list number of files in each subdirectory? But not sum elements from all subdirectories but in each subdirectory start counting from 0.

This is what I tried so far:

$folderCount = $fileCount = $galleryItemCount = 0;
$dir ='./product_img/';
//. means current directory
//if you wanna a learn a folders inside use opendir('path')
$gallery_dir = array();
$gallery_subdir = array();
if ($handle = opendir($dir)) {
    while (false !== ($entry = readdir($handle))) {
        if ($entry != "." && $entry != "..") {
            if (is_dir($dir.$entry)) {
                echo "Folder => " . $entry . "<br>";

                    $gallery_dir[] = $entry;

                    if ($subdir = opendir($dir.$entry)) {
                         while (false !== ($subentry = readdir($subdir))) {
                            if ($subentry != "." && $subentry != "..") {
                                if (!is_dir($subentry) && $gallery_dir[0]) {
                                    echo "Folderrrr => " . $subentry . "<br>";  
                                    $gallery_subdir[] = $subentry;
                                    $galleryItemCount++;
                                    echo $gallery_dir;
                                }
                            }
                         }
                        closedir($subdir);
                    }
                 $folderCount++;
            } else {
                echo "File   => " . $entry . "<br>";
                $fileCount++;
            }
        }
    }
    //echo $galleryItemCount++;
    echo "<br><br>";
    echo "File in aech folder" . $galleryItemCount. "<br />";
    echo "Total Folder Count : " . $folderCount . "<br>" ;
    echo "Total File Count : " . $fileCount;
    closedir($handle);
} 

Upvotes: 4

Views: 901

Answers (3)

akond
akond

Reputation: 16035

$dir = "/some/directory";
$counts = array (
    $dir => 0
);

$iterator = new RecursiveDirectoryIterator ($dir, FilesystemIterator::SKIP_DOTS);
$iterator = new RecursiveIteratorIterator ($iterator, RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $pathname => $file)
{
    if ($file->isDir ())
    {
        $counts [$file->getPathname ()] = 0;
        continue;
    }
    $counts [$file->getPath ()] ++;
}

Upvotes: 2

ion
ion

Reputation: 540

Example function:

    function dirs($dir)
    {
        if ($handle = opendir($dir)) {
            while ($DF = readdir($handle)) {
                if ($DF != '.' && $DF != '..') {
                    $TYPE = is_dir($dir . "/" . $DF)?":DIRS":":FILES";
                    $List[$dir][$TYPE] = isset($List[$dir][$TYPE]) ? ++$List[$dir][$TYPE] : 1;
                    $List[$dir . "/" . $DF] = is_dir($dir . "/" . $DF) ? dirs($dir . "/" . $DF) : $DF;
                }
            }
        }
        return $List;
    }

    var_dump(dirs("framework"));

Will return an array list of files and folders, with a COUNT index for DIRS/FILES

            array (size=9)
      'framework' => 
        array (size=2)
          ':FILES' => int 6
          ':DIRS' => int 2
      'framework/.htaccess' => string '.htaccess' (length=9)
      'framework/composer.json' => string 'composer.json' (length=13)
      'framework/config.ini' => string 'config.ini' (length=10)
      'framework/index.php' => string 'index.php' (length=9)
      'framework/lib' => 
        array (size=24)
          'framework/lib' => 
            array (size=2)
              ':DIRS' => int 3
              ':FILES' => int 20

Upvotes: 0

Gordon
Gordon

Reputation: 316999

You can do this with Iterators. It's a bit tricky to get the file count per folder though.

First, wire up the Iterators. Pass the path you want to traverse:

$iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator(
        '/path/you/want/to/traverse',
        RecursiveDirectoryIterator::SKIP_DOTS
    ),
    RecursiveIteratorIterator::SELF_FIRST
);

The option SKIP_DOTS will make the RecursiveDirectoryIterator ignore . and ... The option SELF_FIRST is required for inclusion of directories. By default, only leaves, e.g. files, are considered.

With the Iterator wired up, you just need to do

foreach ($iterator as $fileObject) {
    if ($fileObject->isDir()) {
        $fileObject->setInfoClass(FilesystemIterator::class);
        $directoryIterator = $fileObject->getFileInfo();
        $directoryIterator->setFlags(FilesystemIterator::SKIP_DOTS);
        $fileCount = iterator_count($directoryIterator);

        echo "$fileObject => $fileCount", PHP_EOL;
    }
}

This will print each folder name along with the file count in each of these folders. Like I said, it's a bit tricky to get the file count. This is because by default the foreach will return SplFileObject instances for the directories. Those are not countable. Thus we need to set the FileSystemIterator. That can be counted.

Note: if FilesystemIterator::class is not supported yet by your PHP Version, either update to a more recent version or pass in 'FileSystemIterator' as a string.

Upvotes: 2

Related Questions