pauldreed Posted January 30, 2018 Share Posted January 30, 2018 The below scans a directory and returns the values as an array using scandir, which works fine. However, I would like it to build the array from 2 directories instead of just one. For example; /home/pi/testDir1 & /home/pi/testDir1 I understand that I need to iterate over both directories, but despite spending hours so far, I just can't get it to work! Any help would be appreciated. Paul <?php $path = "/home/pi/testDir1"; $schema = array(); $dir = scandir($path); for ($i=2; $i<count($dir); $i++) { if (filetype(($path."/").$dir[$i])=='dir' || filetype(($path."/").$dir[$i])=='link') { if (is_file(($path."/").$dir[$i]."/".$dir[$i]."_schema.php")) { require ($path."/").$dir[$i]."/".$dir[$i]."_schema.php"; } } } print_r($schema); Quote Link to comment Share on other sites More sharing options...
dalecosp Posted January 30, 2018 Share Posted January 30, 2018 (edited) Shouldn't be too difficult, either with scandir() or glob() and array_merge(). Keeping track of which dir was which would seem to be the hardest thing in that train of thought.The alternative might be to make your list of dirs an array, looping through it with foreach(). Some people think nested loops are stinky, but I don't see why it wouldn't be apropos here. Edited January 30, 2018 by dalecosp Quote Link to comment Share on other sites More sharing options...
requinix Posted January 30, 2018 Share Posted January 30, 2018 Put the code into a function that takes the starting path as a parameter, then call the function twice for the two directories. Quote Link to comment Share on other sites More sharing options...
pauldreed Posted January 30, 2018 Author Share Posted January 30, 2018 I've tried to use scandir & array_merge, but just can't get it to work. I've got to admit I'm an absolute beginner with php and it seems a very steep learning curve! Has anyone got an example of how this should be written please. Paul Quote Link to comment Share on other sites More sharing options...
requinix Posted January 30, 2018 Share Posted January 30, 2018 Are those included files doing something with $schema? How are they using it? Quote Link to comment Share on other sites More sharing options...
pauldreed Posted January 30, 2018 Author Share Posted January 30, 2018 The actual code is https://github.com/emoncms/emoncms/blob/master/core.php#L115-L130 $schema is used to hold a number of arrays which hold data about modules contained in the /Modules directory. That data is used to load the modules. Paul Quote Link to comment Share on other sites More sharing options...
dalecosp Posted January 30, 2018 Share Posted January 30, 2018 Is this "working" for just one directory? (IOW, are we chasing the correct problem?) Quote Link to comment Share on other sites More sharing options...
dalecosp Posted January 30, 2018 Share Posted January 30, 2018 After some investigation, I'd suggest using is_dir() and is_link() in your testing instead of comparing a value against filetype(). 1 Quote Link to comment Share on other sites More sharing options...
pauldreed Posted January 30, 2018 Author Share Posted January 30, 2018 (edited) Yes, it's currently stable & working fine with one directory. Directory1 = the modules which are installed by the app by default, and come with a standard installation via git Directory2 = a new 'user' directory, where users can add additional modules to increase functionality. I really don't want users adding 'user' modules to 'Directory1'. Thanks for the tip about is_dir() & is_link(). I'll update that. Paul Edited January 30, 2018 by pauldreed Quote Link to comment Share on other sites More sharing options...
Psycho Posted January 31, 2018 Share Posted January 31, 2018 function getSchemas($pathsAry, $suffix) { //Create an array to hold the results $schemasAry = array(); //Iterate over each path foreach($pathsAry as $path) { //Get contents of current path that include the suffix $contents = glob($path.DIRECTORY_SEPARATOR."*{$suffix}"); //Append contents to the results array $schemasAry = array_merge($schemasAry, $contents); } //Returns the results return $schemasAry; } //Define all the paths to process $paths = array("/home/pi/testDir1", "/home/pi/testDir2"); //Get all the files from the provided paths with the defined suffix $schema = getSchemas($paths, '_schema.php'); //Do something with the results echo "<pre>".print_r($schema, TRUE)."</pre>"; Quote Link to comment Share on other sites More sharing options...
pauldreed Posted February 1, 2018 Author Share Posted February 1, 2018 (edited) Thanks Psycho, but I've finally got my head around it! <?php $schema = array(); $path = "/home/pi/path/path/*"; $path1 = "/home/pi/path/path1/*"; $dir1 = glob($path); $dir2 = glob($path1); $dir = (array_merge($dir1,$dir2)); for ($i=2; $i<count($dir); $i++) { if (filetype($dir[$i])=='dir') { $app = basename($dir[$i]); if (is_file($dir[$i]."/".$app."_schema.php")) { require ($dir[$i]."/".$app."_schema.php"); } } } print_r($schema); Edited February 1, 2018 by pauldreed Quote Link to comment Share on other sites More sharing options...
Solution Psycho Posted February 2, 2018 Solution Share Posted February 2, 2018 I think you need to slow down a bit. You are make things harder than they need to be. Plus, when you add a third, fourth, fifth directory you need to modify several lines of code. Write the code so all you have to do is add a directory and not modify the logic. Also, use comments! And, please read documentation for the functions you are using. They have features you are not taking advantage of. The glob() function has a flag to only return directories. Since that is all you are using, you should use it. Don't duplicate logic. E.g. if (is_file($dir[$i]."/".$app."_schema.php")) { require ($dir[$i]."/".$app."_schema.php"); } Creating the string for the full path to the file is a bad idea. If you ever have to change it you run the risk on modifying one and not the other. It probably does not seem like a big deal, but trust me - things like this do happen and debugging them is a pain. Define the full path as a variable and then use that variable in the logic. Using your basic logic, here is a rewrite that is much more flexible and maintainable <?php ## Begin user defined values $dirAry = array( '/home/pi/path/path/', '/home/pi/path/path1/' ); ## End user defined values //Creat array of all sub-directories $subDirAry = array(); foreach($dirAry as $dir) { //Get all items in the directory $items = glob("{$dir}*"); //Remove '.' and '..' $items = array_slice($items, 2); //Append to the subdirectories array $subDirAry = array_merge($subDirAry, $items); } //Create the schema array $schemaFiles = array(); foreach($subDirAry as $subDir) { //Create full path for schema file $app = basename($subDir); $schemaFile = "{$subDir}/{$app}_schema.php"; //Verify that file exists if(file_exists($schemaFile)) { $schemaFiles[] = $schemaFile; require($schemaFile); } } print_r($schema); 1 Quote Link to comment Share on other sites More sharing options...
pauldreed Posted February 2, 2018 Author Share Posted February 2, 2018 Thanks Phsycho. Yes that makes complete sense, and including the paths in an array has already solved another problem that was looming! Many Thanks Paul Quote Link to comment 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.