jackmn1 Posted August 20, 2010 Share Posted August 20, 2010 I need to create a function that lists subfolders of a given folder, that contain at least one .txt file. I found the following function, which displays a list of file that match a pattern in a directory tree: function find($dir, $pattern){ $dir = escapeshellcmd($dir); $files = glob("$dir/$pattern"); foreach (glob("$dir/{.[^.]*,*}", GLOB_BRACE|GLOB_ONLYDIR) as $sub_dir) //look in subdirectories { $arr = find($sub_dir, $pattern); //recursive call $files = array_merge($files, $arr); // merge array with files from subdirectory } return $files; } $txtFiles=find("project/sys","*.txt"); foreach ($txtFiles as $txtFile) { echo '<h2>'.$txtFile.'</h2>'; //display all text files } My question is, how do I change the function to return only folders that contain at least one text file. But, the functions should look inside child folders of "project/sys" and list a child folder only once if that folder or any of its child folders contain at least one text file. I'll give an example of the output I'm looking for: Folder list project/sys/diagram project/sys/bin project/sys/scripts project/sys/styles project/sys/meta The above folders may not contain a text file directly, but their children folders do. However, I'm not interested in their children folder and I want to list the above level folder only once for each folder. Thanks in advance Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/ Share on other sites More sharing options...
kickstart Posted August 20, 2010 Share Posted August 20, 2010 Hi Quick play and something like this should do it <?php function find($dir, $pattern) { $dir = escapeshellcmd($dir); $files = glob("$dir/$pattern"); $retvar = false; if ($files) { $retvar = true; } else { foreach (glob("$dir/{.[^.]*,*}", GLOB_BRACE|GLOB_ONLYDIR) as $sub_dir) //look in subdirectories { $retvar = $retvar || find($sub_dir, $pattern); //recursive call if ($retvar) break; } } return $retvar; } if ($txtFiles=find("project/sys/diagram","*.txt")) echo "Folder project/sys/diagram contains a text file<br />" ; if ($txtFiles=find("project/sys/bin","*.txt")) echo "Folder project/sys/bin contains a text file<br />" ; if ($txtFiles=find("project/sys/scripts","*.txt")) echo "Folder project/sys/scripts contains a text file<br />" ; if ($txtFiles=find("project/sys/styles","*.txt")) echo "Folder project/sys/styles contains a text file<br />" ; if ($txtFiles=find("project/sys/meta","*.txt")) echo "Folder project/sys/meta contains a text file<br />" ; ?> Call it with the base directory name and it will search through sub directories until it finds a text file at which point it will break out of the loop and come back with true. All the best Keith Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101556 Share on other sites More sharing options...
jackmn1 Posted August 20, 2010 Author Share Posted August 20, 2010 Thanks, kickstart, that helps a lot. But the folders I listed are just an example and there are in fact many many more subfolders to project/sys. Therefore I need to somehow find the subfolder list (only 1st level children), and loop through that list instead of the: if ($txtFiles=find("project/sys/diagram","*.txt")) echo "Folder project/sys/diagram contains a text file<br />" ; if ($txtFiles=find("project/sys/bin","*.txt")) echo "Folder project/sys/bin contains a text file<br />" ; if ($txtFiles=find("project/sys/scripts","*.txt")) echo "Folder project/sys/scripts contains a text file<br />" ; Can you show me how to do this? Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101590 Share on other sites More sharing options...
kickstart Posted August 20, 2010 Share Posted August 20, 2010 Hi This will find all the subdirectories of the current directory that contains a text file <?php function find($dir, $pattern) { $dir = escapeshellcmd($dir); $files = glob("$dir/$pattern"); $retvar = false; if ($files) { $retvar = true; } else { foreach (glob("$dir/{.[^.]*,*}", GLOB_BRACE|GLOB_ONLYDIR) as $sub_dir) //look in subdirectories { $retvar = $retvar || find($sub_dir, $pattern); //recursive call if ($retvar) break; } } return $retvar; } $dir = "./"; // Open a current directory and proceed to read its contents if (is_dir($dir)) { if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { if ($file != '.' && $file != '..' && is_dir($file)) { if ($txtFiles=find($dir.$file,"*.txt")) echo "Folder $dir$file contains a text file<br />" ; } } closedir($dh); } } ?> Set $dir to another directory if you do not want to use it on the current directory. All the best Keith Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101595 Share on other sites More sharing options...
jackmn1 Posted August 20, 2010 Author Share Posted August 20, 2010 Great! but the function doesn't output anything, and after debugging, I found out that for some reason it doesn't meet the condition "is_dir". Do you have any idea what might be the reason? Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101601 Share on other sites More sharing options...
kickstart Posted August 20, 2010 Share Posted August 20, 2010 Hi Not sure. Tried it on my PC and it worked OK is_dir is a standard php function to determine if something is a directory. Take out the checks for ".." and "." and double check (including those directories will give some spurious extra lines). All the best Keith Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101614 Share on other sites More sharing options...
jackmn1 Posted August 20, 2010 Author Share Posted August 20, 2010 I did remove the ".." and "." conditions, but is_dir still doesn't work :-( Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101667 Share on other sites More sharing options...
kickstart Posted August 20, 2010 Share Posted August 20, 2010 Hi Looking around there seem to be a fair few people having problems with is_dir depending on file systems, versions of php, etc. One cheat might be to check instead that something isn't a file:- if ($file != '.' && $file != '..' && !is_file($file)) That works on my machine (but then so did is_dir). Give it a try. All the best Keith Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101675 Share on other sites More sharing options...
jackmn1 Posted August 20, 2010 Author Share Posted August 20, 2010 This seems to work a lot better, however, I now noticed that it works only if I leave the $dir variable as $dir = "./", but it doesn't work with $dir = "./project/sys". This is strange, maybe I'm entering the path incorrectly (I'm still a newbie in PHP..). Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101681 Share on other sites More sharing options...
kickstart Posted August 20, 2010 Share Posted August 20, 2010 Hi Is projects a sub directory of the directory the script is in? If so them just put an extra / after sys. All the best Keith Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101683 Share on other sites More sharing options...
jackmn1 Posted August 20, 2010 Author Share Posted August 20, 2010 the script is located in the folder project/extra/scripts/index.php. So what should $dir value be? Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101686 Share on other sites More sharing options...
kickstart Posted August 20, 2010 Share Posted August 20, 2010 Hi It needs to point at the directory you want to search. Ie, assuming project/sys/ is in the root directory then you would need $dir = '/project/sys'; Could also be relative, $dir = '../../../'; All the best Keith Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101696 Share on other sites More sharing options...
jackmn1 Posted August 20, 2010 Author Share Posted August 20, 2010 It works! it wasn't the path eventually, I just realized that there was another is_dir I needed to change to !is_file now. Thanks a lot, kickstart. I appreciate your help. Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101708 Share on other sites More sharing options...
kickstart Posted August 20, 2010 Share Posted August 20, 2010 Hi Glad you got it working. If you want to see a script take ages, run it against the root directory . All the best Keith Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101713 Share on other sites More sharing options...
jackmn1 Posted August 20, 2010 Author Share Posted August 20, 2010 :-) Link to comment https://forums.phpfreaks.com/topic/211257-glob-function-recursive-question/#findComment-1101720 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.