learner007 Posted January 28, 2017 Share Posted January 28, 2017 (edited) I been banging my head over this for sometimes now, But I cant get the result I am after, I was hoping someone can liberate me from the forever circle of mistakes.. function file_match($file_path, array $patterns) { $files = array_diff(scandir($file_path), array('.', '..')); foreach($files as $file) { $full_path = $file_path . DIRECTORY_SEPARATOR . $file; foreach($patterns as $pattern) { if (is_file($full_path)) { if (fnmatch(strtolower($pattern), $file)) { echo $file; echo "<br>"; } } elseif (is_dir($full_path)) { echo $file; echo "<br>"; file_match($full_path, $pattern); } } } } $file_path = 'X:/testfolder1/Monthly Files'; echo file_match($file_path, ['*.doc', '*.zip', '*.pdf]); Expecting result: Directory1 List of files resides inside this directory Directory 2 List of files Resides inside this directory etc like: This is what it should be:Monthly FilesTest File Main 2.PDFTest File Main 1.docJanuary FilesFile January 1.PDFFile January 2.zipFebruary FilesFiles February 1.PDFFiles February 2.PDF etc Edited January 28, 2017 by learner007 Quote Link to comment https://forums.phpfreaks.com/topic/303048-recursive-function-and-too-many-foreach-loop-tangled/ Share on other sites More sharing options...
requinix Posted January 28, 2017 Share Posted January 28, 2017 If fixing file_match($full_path, $pattern);that to use $patterns doesn't solve the problem, what is the current output? Quote Link to comment https://forums.phpfreaks.com/topic/303048-recursive-function-and-too-many-foreach-loop-tangled/#findComment-1542066 Share on other sites More sharing options...
Jacques1 Posted January 28, 2017 Share Posted January 28, 2017 (edited) Note that PHP has several iterators and functions which can traverse directories just fine (and even filter the filenames). There's really no reason to implement that yourself. Edited January 28, 2017 by Jacques1 Quote Link to comment https://forums.phpfreaks.com/topic/303048-recursive-function-and-too-many-foreach-loop-tangled/#findComment-1542068 Share on other sites More sharing options...
requinix Posted January 28, 2017 Share Posted January 28, 2017 Note that PHP has several iterators and functions which can traverse directories just fine (and even filter the filenames). There's really no reason to implement that yourself.Someone (I think it was me) originally suggested the RecursiveDirectoryIterator in another thread, but the output requirements made it easier to use scandir/glob and do the recursion manually. ...at least that's what I remember. I thought it was supposed to show files before directories too, but the posted code won't do that. Quote Link to comment https://forums.phpfreaks.com/topic/303048-recursive-function-and-too-many-foreach-loop-tangled/#findComment-1542069 Share on other sites More sharing options...
learner007 Posted January 28, 2017 Author Share Posted January 28, 2017 Note that PHP has several iterators and functions which can traverse directories just fine (and even filter the filenames). There's really no reason to implement that yourself. I've tried with DirectoryIterator but I couldnt get it to work and the output result was not as expected. Would you be able to give examples of codes? Quote Link to comment https://forums.phpfreaks.com/topic/303048-recursive-function-and-too-many-foreach-loop-tangled/#findComment-1542070 Share on other sites More sharing options...
learner007 Posted January 28, 2017 Author Share Posted January 28, 2017 (edited) Someone (I think it was me) originally suggested the RecursiveDirectoryIterator in another thread, but the output requirements made it easier to use scandir/glob and do the recursion manually. ...at least that's what I remember. I thought it was supposed to show files before directories too, but the posted code won't do that. Mr requinix, I've posted this on devshed, I've taken your suggestions and got the codes to work this far, now stuck to this point. I've never done nested foreach loop before, I cant get foreach loop to behave correctly, listing same file and directory more than once? Also the root directory name should show on top and files inside it should show just below it but instead just get listed anywhere in the list of files. After correcting the file_match($full_path, $patterns) Also I've renamed few files so that I can follow what directory they belong to. The output result I got: February Files February File 1.pdf February File 2.pdf February Files February File 1.pdf February File 2.pdf February Files February File 1.pdf February File 2.pdf File List.pdf January Files January File 1.pdf January File 2.pdf January Files January File 1.pdf January File 2.pdf January Files January File 1.pdf January File 2.pdf Read First.pdf Zip File.zip word.docx Output should be like this: Monthly Files Read First.pdfZip File.zip word.docx January FilesJanuary File 1.pdf January File 2.pdf February FilesFebruary File 1.pdf February File 2.pdf Edited January 28, 2017 by learner007 Quote Link to comment https://forums.phpfreaks.com/topic/303048-recursive-function-and-too-many-foreach-loop-tangled/#findComment-1542072 Share on other sites More sharing options...
requinix Posted January 28, 2017 Share Posted January 28, 2017 Oh, right, that was it. If you want to separate files and directories then you need to separate the files from the directories: go through the directory putting files into one array and directories into another. Afterwards you can print out all the files and then all the directories. // obviously not actual php code: files = [] directories = [] for each thing in directory { if thing is file { files[] = thing } else { directories[] = thing } } for each file in files { show file } for each dir in directories { show header call file_match recursively }But since scandir() does not sort filenames, you'll need to do that yourself with sort() - before the output happens. You could use glob, which does sort, but it also returns the full file path so one way or another you'll have an extra line of code somewhere. sort($files); Quote Link to comment https://forums.phpfreaks.com/topic/303048-recursive-function-and-too-many-foreach-loop-tangled/#findComment-1542073 Share on other sites More sharing options...
learner007 Posted January 28, 2017 Author Share Posted January 28, 2017 Oh, right, that was it. I hope I am not confusing you? I dont want the results to have all files in one list and all directories in separate list. I dont mind the way code is listing the files and directories, but it is duplicating the results, if you look at my previous post you can see the files and directories of same name listing several times. How to fix that? Quote Link to comment https://forums.phpfreaks.com/topic/303048-recursive-function-and-too-many-foreach-loop-tangled/#findComment-1542075 Share on other sites More sharing options...
Jacques1 Posted January 28, 2017 Share Posted January 28, 2017 (edited) So, how does this not do what you want: <?php const PATH = 'X:/testfolder1/Monthly Files'; const EXTENSIONS = ['doc', 'zip', 'pdf']; $dirIterator = new RecursiveDirectoryIterator(PATH, RecursiveDirectoryIterator::SKIP_DOTS); $fileIterator = new RecursiveIteratorIterator($dirIterator, RecursiveIteratorIterator::SELF_FIRST); foreach ($fileIterator as $file) { if ($file->isDir() || ($file->isFile() && in_array(strtolower($file->getExtension()), EXTENSIONS))) { echo "$file<br>"; } } Edited January 28, 2017 by Jacques1 Quote Link to comment https://forums.phpfreaks.com/topic/303048-recursive-function-and-too-many-foreach-loop-tangled/#findComment-1542076 Share on other sites More sharing options...
learner007 Posted January 29, 2017 Author Share Posted January 29, 2017 (edited) So, how does this not do what you want: <?php const PATH = 'X:/testfolder1/Monthly Files'; const EXTENSIONS = ['doc', 'zip', 'pdf']; $dirIterator = new RecursiveDirectoryIterator(PATH, RecursiveDirectoryIterator::SKIP_DOTS); $fileIterator = new RecursiveIteratorIterator($dirIterator, RecursiveIteratorIterator::SELF_FIRST); foreach ($fileIterator as $file) { if ($file->isDir() || ($file->isFile() && in_array(strtolower($file->getExtension()), EXTENSIONS))) { echo "$file<br>"; } } This will work, with basename this will list the directories and files. const PATH = 'X:/testfolder1/Monthly Files'; const EXTENSIONS = ['doc', 'zip', 'pdf']; $dirIterator = new RecursiveDirectoryIterator(PATH, RecursiveDirectoryIterator::SKIP_DOTS); $fileIterator = new RecursiveIteratorIterator($dirIterator, RecursiveIteratorIterator::SELF_FIRST); echo basename(PATH); echo "<br><br>"; foreach ($fileIterator as $file) { if ($file->isDir() || ($file->isFile() && in_array(strtolower($file->getExtension()), EXTENSIONS))) { echo basename($file)."<br>"; } } output: Monthly Files <------------root folder February Files <----------------sub folder February File 1.pdf February File 2.pdf File List.pdf <--------------root files January Files <------------- sib folder January File 1.pdf January File 2.pdf Read First.pdf <----------- root file Zip File.zip <--------------- root file How can I achieve this: List any root files in the root folder listing first, Then any sub folder and its contents listing? Monthly Files <------------root folder Read First.pdf <----------- root file Zip File.zip <--------------- root file File List.pdf <--------------root file February Files <----------------sub folder February File 1.pdf February File 2.pdf January Files <---------sub folder January File 1.pdf January File 2.pdf Edited January 29, 2017 by learner007 Quote Link to comment https://forums.phpfreaks.com/topic/303048-recursive-function-and-too-many-foreach-loop-tangled/#findComment-1542084 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.