skip to Main Content

So I have a series of directories, that contain other subdirectories that contain other subdirectories and so on to arrive to the .jpg files.
Now each subdirectory has a different number of subdirectories itself and I need the code to scan through the main and go through each and count the number of .jpg files, only those.

The structure is:

**MAIN DIRECTORY (Television)**

--**Subdirectory #1** 
---Subdirectory 
----Subdirectory 
-----jpg Files (*1*)

--**Subdirectory #2** 
---Subdirectory 
----Subdirectory
-----Subdirectory
------jpg Files (*114*)

This was my code to display the sub-directories of category "Television" and count the number of albums each has

$path    = '.'; 
$files = array_diff(scandir($path, 1), array('.', '..', 'index.php', 'error_log')); 
foreach(array_unique($files) as $file) {
    echo "<tr>";
    echo "<td class='catrow'>";
    echo "<div class='categories'>";
    echo "<span class='catlink'><a href='$file'>";
    echo preg_replace(array('/_/', '/--/', '/=/',), array(' ', '&#x27', '&#x3A '), $file). "</a>";
    echo "</span>";
    echo "<div class='albums-count'><span>";
    echo "This category has <b>" . count(array_diff(scandir($file), array('.', '..', 'index.php', 'error_log') )) . "</b> albums.";
    echo "</span></div>";
    echo "</td>";
    echo "<td class='catrow' align='center'><span class='photos-count'><b>";
    echo ***FILES COUNT GOES HERE***
    echo "</b><br>photos</span></td>";
    echo "</td>";
    echo "</tr>";
}   

Browsing I found this https://stackoverflow.com/a/41848361/23556208 which at least seemed to be showing a number, not the right one though. And repeated in loop the same one.

How do I get this right?

2

Answers


  1. Chosen as BEST ANSWER

    Temporary method that's working

    echo count(glob($file. "*/*/*/*.{jpg}",GLOB_BRACE));
    

    where each * represents how deep into that search it needs to go


  2. To count the total number of JPEG files recursively, one could use RecursiveIteratorIterator based on RecursiveDirectoryIterator and CallbackFilterIterator to filter only JPEG files, e.g.:

    <?php
    /**
     * Recursively count the number of JPEG files in a directory.
     *
     * @param string $directory The directory to search for JPEG files
     * @param int $depth The maximum depth. -1 means no limit.
     * @return int The number of JPEG files found.
     */
    function countJpgFiles(string $directory, int $depth = -1): int
    {
        $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator(
                $directory,
                FilesystemIterator::SKIP_DOTS
                | FilesystemIterator::FOLLOW_SYMLINKS
            )
        );
        $files->setMaxDepth($depth);
    
        $jpgFiles = new CallbackFilterIterator(
            $files,
            fn (SplFileInfo $file): bool => isJpgFile($file)
        );
    
        return iterator_count($jpgFiles);
    }
    
    /**
     * Check if a file is a JPEG file.
     *
     * @param SplFileInfo $file The file to check
     * @return bool True if the file is a JPEG file, false otherwise.
     */
    function isJpgFile(SplFileInfo $file): bool
    {
        $extension = strtolower($file->getExtension());
    
        return $file->isFile() && ($extension === 'jpg' || $extension === 'jpeg');
    }
    
    

    To count the files in the subdirectories, list the top-level directories using DirectoryIterator or FilesystemIterator and count the JPEG files in each of them, e.g.:

    <?php
    /**
     * List the top-level directories in a directory.
     * @return iterable<SplFileInfo>
     */
    function listTopLevel(string $directory): iterable
    {
        $directories = new FilesystemIterator(
            $directory,
            FilesystemIterator::SKIP_DOTS
            | FilesystemIterator::CURRENT_AS_FILEINFO
            | FilesystemIterator::FOLLOW_SYMLINKS
        );
    
        foreach ($directories as $directory) {
            if ($directory->isDir()) {
                yield $directory;
            }
        }
    }
    
    $mainDir = './gallery/Television'; // TODO Change this to your top-level directory
    $lineFormat = "%-30s%10dn";
    $prefix = '    ';
    
    printf($lineFormat, "JPEGs in $mainDir", countJpgFiles($mainDir));
    printf($lineFormat, "{$prefix}top-level", countJpgFiles($mainDir, 0));
    
    foreach (listTopLevel($mainDir) as $subDir) {
        printf(
            $lineFormat,
            $prefix . $subDir->getPathname(),
            countJpgFiles($subDir->getPathname())
        );
    }
    

    Let’s say we have the following directory structure:

    gallery/Television
    ├── Sub1
    │   ├── sub.jpg
    │   ├── Sub-Sub1
    │   │   ├── one.jpg
    │   │   └── two.jpg
    │   └── Sub-Sub2
    │       ├── one.jpg
    │       ├── sub-sub-two.jpg
    │       └── two.jpg
    ├── Sub2
    │   ├── sub.jpg
    │   ├── Sub-Sub1
    │   │   ├── one.jpg
    │   │   ├── sub2sub-sub.jpg
    │   │   └── two.jpg
    │   └── Sub-Sub2
    │       ├── one.jpg
    │       ├── sub2sub-sub.jpg
    │       ├── sub-sub-two.jpg
    │       └── two.jpg
    └── top-level.jpg
    

    Then, the output of the script would be:

    JPEGs in ./gallery/Television         15
        top-level                          1
        ./gallery/Television/Sub1          6
        ./gallery/Television/Sub2          8
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search