Get specific files in a Recursive Directory

2.1k Views Asked by At

Following a given example by a comment in the php.net manual I am trying to grab each file named file.txt in a recursively directory structure.

Folder/
  subfold1
   subfold2
     file.txt

   subfold3
     file.txt

etc. is a example on how the folder structure may look like.

    $directory = new \RecursiveDirectoryIterator(__DIR__ . '/..');

    $iterator = new \RecursiveIteratorIterator($directory);

    $files = new \RegexIterator($iterator, '/^file.txt$/', \RecursiveRegexIterator::GET_MATCH);

    var_dump($files);

The problem is that the given code is giving the following result:

object(RegexIterator)#4 (1) { ["replacement"]=> NULL }

What should I do with it? I am simply looking for the file and the given path, preferably in an array.

1

There are 1 best solutions below

0
On

You generally want to iterate over the *Iterator object, most often using a basic foreach() loop.

foreach ($files as $file) {
    // Do something
}

In your case, the work is a little more involved because the code that you are using at the moment will never return any matching files to iterate. First, let's see what should work.

$directory = new RecursiveDirectoryIterator(
    __DIR__ . '/..',
    RecursiveDirectoryIterator::KEY_AS_FILENAME | 
    RecursiveDirectoryIterator::CURRENT_AS_FILEINFO
);
$files = new RegexIterator(
    new RecursiveIteratorIterator($directory),
    '#^file\.txt$#',
    RegexIterator::MATCH,
    RegexIterator::USE_KEY
);

The key take-home changes are:

  • The RecursiveDirectoryIterator::KEY_AS_FILENAME flag for the RecursiveDirectoryIterator, used in combination with
  • The RegexIterator::USE_KEY flag for the RegexIterator`

Previously, as the iterator was being iterated, the regex would be matching against the "current" iterator value which in your case was an SplFileInfo object representing each file. When cast to a string, for the regex to do its matching, the SplFileInfo objects were turned into their full path; directories and all. This meant that your regex would never match since it is only expecting the file name.

To cut a long story short, the KEY_AS_FILENAME and USE_KEY flags mean that the regex is working on just the file name for each file. Yay!

You may also notice that I have used the RegexIterator in RegexIterator::MATCH mode. This means that upon looping over the matched files, we have full access to each SplFileInfo object. This gives us much more to play with than just a string with the file name as RegexIterator::GET_MATCH would provide.

To print out each of the files, with their full paths, you could use something like:

foreach ($files as $file) {
    echo $file->getPathname() . "\n";
}

See the SplFileInfo documentation for a full list of methods available.