Recursion through a directory tree in PHP
I have a set of folders that has a depth of at least 4 or 5 levels. I’m looking to recurse through the directory tree as deep as it goes, and iterate over every file. I’ve gotten the code to go down into the first sets of subdirectories, but no deeper, and I’m not sure why. Any ideas?
$count = 0; $dir = "/Applications/MAMP/htdocs/site.com"; function recurseDirs($main, $count) < $dir = "/Applications/MAMP/htdocs/site.com"; $dirHandle = opendir($main); echo "here"; while($file = readdir($dirHandle))< if(is_dir($file) && $file != '.' && $file != '..')< echo "isdir"; recurseDirs($file); >else< $count++; echo "$count: filename: $file in $dir/$main \n
"; > > > recurseDirs($dir, $count);
4 Answers 4
It’s still far from perfect as you can’t order the search results and other things, but to simply get a list of files, it’s fine.
There are simple examples to get you started in the manual like this one:
Just one remark: an iterator does what it’s name implies. It iterates over an iterable source. That’s no different from iterating over an array. If you’d want the results sorted, then you’d have to do this in the foreach loop or write/use a function to do this for you.
@Gordon true. But being able to get the results sorted and/or filtered straight away is a feature I would expect from a recursive directory iterator nevertheless — I understand that that may not be in the spririt of the SPL, but still. As it is, there is again the need to come up with dozens of lines of code (with hundreds of snippets on the net, all varying in quality) to perform a pretty standard task, where other languages offer ready-made functions. That pisses me off a bit sometimes.
@Pekka Since everything can be an Iterable now, it is impossible to come up with a generic sort. How should it know I want my Person objects to be sorted by $firstName but my Files by MTime? You have to script that. If you want to query objects by generic expressions, have a look at PHPLinq.
@Gordon true, and not the job of an iterator. I guess what I’m trying to say is, I would like to see a PHP standard library for file operations that is better and more powerful than what is available right now.
@Pekka have a look at github.com/theseer/DirectoryScanner or github.com/sebastianbergmann/php-file-iterator then. Also, I am currently in the process of writing a FilterIterator that allows for filtering based on File attributes.
There is an error in the call
you have to give the full path:
recurseDirs($main . '/' .$file, $count);
However, like other anwerers, I suggest to use RecursiveDirectoryIteretor .
The call to is_dir and recurseDirs is not fully correct. Also your counting didn’t work correctly. This works for me:
$dir = "/usr/"; function recurseDirs($main, $count=0)< $dirHandle = opendir($main); while($file = readdir($dirHandle))< if(is_dir($main.$file."/") && $file != '.' && $file != '..')< echo "Directory :
"; $count = recurseDirs($main.$file."/",$count); // Correct call and fixed counting > else< $count++; echo "$count: filename: $file in $main \n
"; > > return $count; > $number_of_files = recurseDirs($dir);
Notice the changed calls to the function above and the new return value of the function.
So yeah: Today I was being lazy and Googled for a cookie cutter solution to a recursive directory listing and came across this. As I ended up writing my own function (as to why I even spent the time to Google for this is beyond me — I always seem to feel the need to re-invent the wheel for no suitable reason) I felt inclined to share my take on this.
While there are opinions for and against the use of RecursiveDirectoryIterator, I’ll simply post my take on a simple recursive directory function and avoid the politics of chiming in on RecursiveDirectoryIterator.
function recursiveDirectoryList( $root ) < /* * this next conditional isn't required for the code to function, but I * did not want double directory separators in the resulting array values * if a trailing directory separator was provided in the root path; * this seemed an efficient manner to remedy said problem easily. */ if( substr( $root, -1 ) === DIRECTORY_SEPARATOR ) < $root = substr( $root, 0, strlen( $root ) - 1 ); >if( ! is_dir( $root ) ) return array(); $files = array(); $dir_handle = opendir( $root ); while( ( $entry = readdir( $dir_handle ) ) !== false ) < if( $entry === '.' || $entry === '..' ) continue; if( is_dir( $root . DIRECTORY_SEPARATOR . $entry ) ) < $sub_files = recursiveDirectoryList( $root . DIRECTORY_SEPARATOR . $entry . DIRECTORY_SEPARATOR ); $files = array_merge( $files, $sub_files ); >else < $files[] = $root . DIRECTORY_SEPARATOR . $entry; >> return (array) $files; >
With this function, the answer as to obtaining a file count is simple:
$dirpath = '/your/directory/path/goes/here/'; $files = recursiveDirectoryList( $dirpath ); $number_of_files = sizeof( $files );
But, if you don’t want the overhead of an array of the respective file paths — or simply don’t need it — there is no need to pass a count to the recursive function as was recommended.
One could simple amend my original function to perform the counting as such:
function recursiveDirectoryListC( $root ) < $count = 0; if( ! is_dir( $root ) ) return (int) $count; $dir_handle = opendir( $root ); while( ( $entry = readdir( $dir_handle ) ) !== false ) < if( $entry === '.' || $entry === '..' ) continue; if( is_dir( $root . DIRECTORY_SEPARATOR . $entry ) ) < $count += recursiveDirectoryListC( $root . DIRECTORY_SEPARATOR . $entry . DIRECTORY_SEPARATOR ); >else < $count++; >> return (int) $count; >
In both of these functions the opendir() function should really be wrapped in a conditional in the event that the directory is not readable or another error occurs. Make sure to do so correctly:
if( ( $dir_handle = opendir( $dir ) ) !== false ) < /* perform directory read logic */ >else < /* do something on failure */ >
Источник
Рекурсивный обход дерева
Добрый вечер!
Не получается доделать рекурсивный обход дерева.(PHP недавно начал осваивать. )
Не могу понять как вывести на экран НЕ родителей X,D,Y,Z.
Пытался их вывести,но получалось либо куча ошибок либо выводилось только ABXCZ ,а D и Y не выводились,сейчас остановился на таком коде:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
$A=['A' => [ 'B' => ['X','D','Y'], 'C' => ['Z'] ] ]; //print_r($A); function recursion($A){ foreach($A as $children => $child) { if($children == NULL) return; echo $children."\n"; if(is_array($child)){ recursion($child); } } } recursion($A);
Рекурсивный обход и помещение данных в массив
Здравствуйте, может кто подскажет, есть рекрсивный обход файлов и папок с помощью iteration .
Обход бинарного дерева без рекурсии
Помогите, два дня уже мучаюсь, не пойму как перебрать дерево: с неограниченным числом вложений, без.
Рекурсивный обход дерева
Помогите пожалуйста решить задачу, про методы расширения прочитал..Тут нужно использовать свойство.
Рекурсивный обход небинарного дерева
Здравствуйте. бьюсь над задачей уже долго, но без помощи, чувствую, никак. Есть дерево.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
$A = array( 'A' => array( 'B' => array( 'X', 'D', 'Y'), 'C' => array( 'Z' ) ) ); function recursion($A){ foreach($A as $children => $child) { foreach ($child as $k => $v) { foreach ($v as $k => $val) { echo $val; } } } } echo recursion($A);
конечно не уверен что именно это вам нужно было)
hardwaremaster, спасибо, но необходимо чтобы вывод был такой :
A
—B
——X
——D
——Y
—C
——Z
Добавлено через 46 минут
И обход дерева должен быть рекурсивный.
Сообщение от bladzher
здесь вы смешиваете имена ключей и значения переменных
Добавлено через 2 минуты
вам нужно либо оптимизировать содержание массива, либо вы получите примерно следующую структуру:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
$A = array( 'A' => array( 'B' => array( 'X', 'D', 'Y'), 'C' => array( 'Z' ) ) ); function get_child($arr,$level=0){ $res = ''; if(is_array($arr)){ foreach ($arr as $k => $value) { $res.= '
'.str_pad("", $level, '-').$k; if(is_array($value))$res .= get_child($value,$level+1); if(is_string($value))$res .= '
'.str_pad("", $level, '-').$value; } } return $res; return '
'.str_pad("", $level, '-').$res; } echo get_child($A);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
$A = array( 'A' => array( 'B' => array( 'X', 'D', 'Y'), 'C' => array( 'Z' ), 'G' => array( 'H' => array( 'J', 'K', 'L'), 'I' => array( 'M' ) ) ) ); function get_sep($level){return '
'.str_pad("", $level*3, '-');} function get_child($arr,$level=0){ $res = ''; if(is_array($arr)){ foreach ($arr as $k => $value) { $res.= get_sep($level).$k; if(is_array($value))$res .= get_child($value,$level+1); if(is_string($value))$res .= get_sep($level+1).$value; } } return $res; return get_sep($level).$res; } echo get_child($A);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
A ---B ------0 ---------X ------1 ---------D ------2 ---------Y ---C ------0 ---------Z ---G ------H ---------0 ------------J ---------1 ------------K ---------2 ------------L ------I ---------0 ------------M
Рекурсивный обход НЕбинарного дерева
Имеется функция, которая рекурсивно обходит одну папку. void GetFileList(LPTSTR sPath, Object*.
Инфиксный рекурсивный обход дерева
Задача написать инфиксный рекурсивный обход BST-дерева. Возвращает IEnumerable<int>. Написала.
Рекурсивный обход дерева папок
Вот код рекурсивного обхода всех папок в директории : procedure FindFiles(const DirPath: string;.
Рекурсивный обход дерева, не являющегося бинарным
Пожскажите, пожалуйста, как организоват рекурсивный обход небинарного дерева.
Рекурсивный обход реестра и формирование дерева Treeview
Недавно видел код на обход реестра и добавления его в TreeView. Проблема в том, что просматривается.
Рекурсивный обход дерева каталогов с изменением вложенных файлов
Нет ли у кого-нибудь желания написать скрипт для решения следующей задачи.
Источник