Jump to content
pauldreed

scandir - iterate over 2 directories

Recommended Posts

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);

Share this post


Link to post
Share on other sites

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 by dalecosp

Share this post


Link to post
Share on other sites

Put the code into a function that takes the starting path as a parameter, then call the function twice for the two directories.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Are those included files doing something with $schema? How are they using it?

Share this post


Link to post
Share on other sites

After some investigation, I'd suggest using is_dir() and is_link() in your testing instead of comparing a value against filetype().

  • Like 1

Share this post


Link to post
Share on other sites

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 by pauldreed

Share this post


Link to post
Share on other sites

 

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>";

Share this post


Link to post
Share on other sites

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 by pauldreed

Share this post


Link to post
Share on other sites

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);
  • Like 1

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.