35

I'm trying to return the files in a specified directory using a recursive search. I successfully achieved this, however I want to add a few lines of code that will allow me to specify certain extensions that I want to be returned.

For example return only .jpg files in the directory.

Here's my code,

<?php $it = new RecursiveDirectoryIterator("L:\folder\folder\folder"); foreach(new RecursiveIteratorIterator($it) as $file) { echo $file . "<br/> \n"; } ?> 

please let me know what I can add to the above code to achieve this, thanks

9 Answers 9

47
<?php $it = new RecursiveDirectoryIterator("L:\folder\folder\folder"); $display = Array ( 'jpeg', 'jpg' ); foreach(new RecursiveIteratorIterator($it) as $file) { if (in_array(strtolower(array_pop(explode('.', $file))), $display)) echo $file . "<br/> \n"; } ?> 
Sign up to request clarification or add additional context in comments.

1 Comment

Only variables should be passed by reference
20

You should create a filter:

class JpegOnlyFilter extends RecursiveFilterIterator { public function __construct($iterator) { parent::__construct($iterator); } public function accept() { return $this->current()->isFile() && preg_match("/\.jpe?g$/ui", $this->getFilename()); } public function __toString() { return $this->current()->getFilename(); } } $it = new RecursiveDirectoryIterator("L:\folder\folder\folder"); $it = new JpegOnlyFilter($it); $it = new RecursiveIteratorIterator($it); foreach ($it as $file) ... 

1 Comment

This will not work, if you stop when found a directory (if ->isFile()) the iterator don't deep in that directory to scan more files and directories, is more complex than one-line if.
8

Try this, it uses an array of allowed file types and only echos out the file if the file extension exists within the array.

<?php $it = new RecursiveDirectoryIterator("L:\folder\folder\folder"); $allowed=array("pdf","txt"); foreach(new RecursiveIteratorIterator($it) as $file) { if(in_array(substr($file, strrpos($file, '.') + 1),$allowed)) { echo $file . "<br/> \n"; } } ?> 

You may also find that you could pass an array of allowed file types to your RecursiveDirectoryIterator class and only return files that match.

Comments

6

Let PHP do the job:

$directory = new RecursiveDirectoryIterator('path/to/directory/'); $iterator = new RecursiveIteratorIterator($directory); $regex = new RegexIterator($iterator, '/\.jpe?g$/i', RecursiveRegexIterator::GET_MATCH); echo '<pre>'; print_r($regex); 

1 Comment

print_r($regex); just give me... RegexIterator Object ( [replacement] => ) php.net/manual/en/regexiterator.construct.php It is needed to loop with something such as foreach. foreach ($regexIterator as $value) { echo $value . "\n"; }
1

Regarding the top voted answer: I created this code which is using fewer functions, only 3, isset(), array_flip(), explode() instead of 4 functions. I tested the top voted answer and it was slower than mine. I suggest giving mine a try:

$it = new RecursiveDirectoryIterator("L:\folder\folder\folder"); foreach(new RecursiveIteratorIterator($it) as $file) { $FILE = array_flip(explode('.', $file)); if (isset($FILE['php']) || isset($FILE['jpg'])) { echo $file. "<br />"; } } 

1 Comment

This breaks on a case like php.png. It is not a php or jpg file; it is an png file named php. It is important to precisely extract the file extension when validating. Speed of execution is moot if it doesn't deliver the desired effect.
1

None of these worked for my case. So i wrote this function, not sure about efficiency, I just wanted to remove some duplicate photos quickly. Hope it helps someone else.

function rglob($dir, $pattern, $matches=array()) { $dir_list = glob($dir . '*/'); $pattern_match = glob($dir . $pattern); $matches = array_merge($matches, $pattern_match); foreach($dir_list as $directory) { $matches = rglob($directory, $pattern, $matches); } return $matches; } $matches = rglob("C:/Bridge/", '*(2).ARW'); 

Only slight improvement that could be made is that currently for it to work you have to have a trailing forward slash on the start directory.

Comments

1

In this sample code;

  • You can set any path for $directory variable, for example ./, 'L:\folder\folder\folder' or anythings...
  • And also you can set a pattern file name in $pattern optional, You can put '/\.jpg$/' for every file with .jpg extension, and also if you want to find all files, can just use '//' for this variable.
$directory = 'L:\folder\folder\folder'; $pattern = '/\.jpg$/'; //use "//" for all files $directoryIterator = new RecursiveDirectoryIterator($directory); $iteratorIterator = new RecursiveIteratorIterator($directoryIterator); $regexIterator = new RegexIterator($iteratorIterator, $pattern); foreach ($regexIterator as $file) { if (is_dir($file)) continue; echo "$file\n"; } 

Comments

0

here is the correct way to search in folders and sub folders

$it = new RecursiveDirectoryIterator(__DIR__); $findExts = Array ( 'jpeg', 'jpg' ); foreach(new RecursiveIteratorIterator($it) as $file) { $ext = pathinfo($file, PATHINFO_EXTENSION); if(in_array($ext, $findExts)){ echo $file.PHP_EOL; } } 

Comments

-1

You might want to check out this page about using glob() for a similar search:

http://www.electrictoolbox.com/php-glob-find-files/

2 Comments

Your source is good, but try give a constructive answer with example, how to resource can be used for the particular case and only add the link as reference.
I don't think glob handles recursion, either, which was a part of the question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.