wikinevis
wikinevis

Reputation: 189

how to get all subdirectories that has specific folder name in php?

I find out that I can get all subdirectories of the folder with below code in php

$address = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($root, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST,
RecursiveIteratorIterator::CATCH_GET_CHILD // Ignore "Permission denied"
);

and put it in the $address.

How can I add one more criteria and say if the subdirectory has the 'tmp' folder inside it, then put it in the $address ?

Upvotes: 3

Views: 1225

Answers (2)

hakre
hakre

Reputation: 198206

You probably can add the criteria by creating yourself a FilterIterator that checks for a subdirectory. The following usage example demonstrates this to list folders I have under git.

$address is what you have in your question already, the filter is just added around:

$filtered = new SubDirFilter($address, '.git');

foreach ($filtered as $file) {
    echo $filtered->getSubPathname(), "\n";
}

Output:

Artax
CgiHttpKernel
CgiHttpKernel/vendor/silex/silex
...
composer
composer-setup
CVBacklog
...

And what not. This filter-iterator used is relatively straight forward, for each entry it's checked whether it has that subdiretory or not. It is important that you have the FilesystemIterator::SKIP_DOTS enabled for this (which you have) otherwise you will get duplicate results (expressing the same directory):

class SubDirFilter extends FilterIterator
{
    private $subDir;

    public function __construct(Iterator $iterator, $subDir) {
        $this->subDir = $subDir;
        parent::__construct($iterator);
    }

    public function accept() {
        return is_dir($this->current() . "/" . $this->subDir);
    }
}

Upvotes: 3

Baba
Baba

Reputation: 95161

You can create your own RecursiveFilterIterator

$dir = new RecursiveDirectoryIterator(__DIR__, 
        RecursiveDirectoryIterator::SKIP_DOTS);

$address = new RecursiveIteratorIterator(new TmpRecursiveFilterIterator($dir), 
        RecursiveIteratorIterator::SELF_FIRST, 
        RecursiveIteratorIterator::CATCH_GET_CHILD);


foreach($address as $dir) {
    echo $dir,PHP_EOL;
}

Class Used

class TmpRecursiveFilterIterator extends RecursiveFilterIterator {
    public function accept() {
        $file = $this->current();
        if ($file->isDir()) {
            return is_dir("$file/tmp");
        }
        return false;
    }
}

Upvotes: 4

Related Questions