I have set up a basic script that is posting an array of paths to find template files inside them; currently it\'s only searching two levels deep and I\'m having some troubles g
Here is working code which scans given directory $dir and all of its sub directories to any levels and return list of html files and folders containing them.
<?php
function find_all_files($dir)
{
if(!is_dir($dir)) return false;
$pathinfo = '';
$root = scandir($dir);
foreach($root as $value)
{
if($value === '.' || $value === '..') {continue;}
if(is_file("$dir/$value")) {
$pathinfo = pathinfo($dir.'/'.$value);
if($pathinfo['extension'] == 'html') {
$result[]="$dir/$value";
}
continue;
}
foreach(find_all_files("$dir/$value") as $value)
{
$result[]=$value;
}
}
return $result;
}
//call function
$res = find_all_files('physical path to folder');
print_r($res);
?>
Universal File search in folder, sub-folder :
function dirToArray($dir,$file_name) {
$result = array();
$cdir = scandir($dir);
foreach ($cdir as $key => $value)
{
if (!in_array($value,array(".","..")))
{
if (is_dir($dir . DIRECTORY_SEPARATOR . $value))
{
$result[$value] = dirToArray($dir . DIRECTORY_SEPARATOR . $value,$file_name);
}
else
{
if($value == $file_name){
$result[] = $value;
}
}
}
}
return $result;
}
define('ROOT', dirname(__FILE__));
$file_name = 'template.html';
$tree = dirToArray(ROOT,$file_name);
echo "<pre>".print_r($tree,1)."</pre>";
OUTPUT :
Array
(
[components] => Array
(
[side] => Array
(
[second] => Array
(
[0] => template.html
[third] => Array
(
[0] => template.html
)
)
[0] => template.html
)
[0] => template.html
)
[0] => template.html
)
Alternative of my previous answer :
$dir = 'components';
function getFiles($dir, &$results = array(), $filename = 'template.html'){
$files = scandir($dir);
foreach($files as $key => $value){
$path = realpath($dir.'/'.$value);
if(!is_dir($path)) {
if($value == $filename)
$results[] = $path;
} else if($value != "." && $value != "..") {
getFiles($path, $results);
}
}
return $results;
}
echo '<pre>'.print_r(getFiles($dir), 1).'</pre>';
OUTPUT :
Array
(
[0] => /web/practise/php/others/test7/components/side/second/template.html
[1] => /web/practise/php/others/test7/components/side/second/third/template.html
[2] => /web/practise/php/others/test7/components/side/template.html
[3] => /web/practise/php/others/test7/components/template.html
)
Another solution is using Finder component from Symfony. It's tested and proven code. Take a look at it here: http://symfony.com/doc/current/components/finder.html
PHP has the perfect solution for you built in.
// Construct the iterator
$it = new RecursiveDirectoryIterator("/components");
// Loop through files
foreach(new RecursiveIteratorIterator($it) as $file) {
if ($file->getExtension() == 'html') {
echo $file;
}
}
PHP 5 introduces iterators to iterate quickly through many elements.
You can use RecursiveDirectoryIterator to iterate recursively through directories.
You can use RecursiveIteratorIterator on the result to have a flatten view of the result.
You can use RegexIterator on the result to filter based on a regular expression.
$directory_iterator = new RecursiveDirectoryIterator('.');
$iterator = new RecursiveIteratorIterator($directory_iterator);
$regex_iterator = new RegexIterator($iterator, '/\.php$/');
$regex_iterator->setFlags(RegexIterator::USE_KEY);
foreach ($regex_iterator as $file) {
echo $file->getPathname() . PHP_EOL;
}
With iterators, there are lot of ways to do the same thing, you can also use a FilterIterator (see the example on the page)
For instance, if you want to select the files modified this week, you can use the following:
$directory_iterator = new RecursiveDirectoryIterator('.');
$iterator = new RecursiveIteratorIterator($directory_iterator);
class CustomFilterIterator extends FilterIterator {
function accept() {
$current=$this->getInnerIterator()->current();
return ($current->isFile()&&$current->getMTime()>time()-3600*24*7);
}
}
$filter_iterator=new CustomFilterIterator($iterator);
foreach ($filter_iterator as $file) {
echo $file->getPathname() . PHP_EOL;
}