简体   繁体   中英

Looping over all subdirectories of a directory

I have a task that should be simple,

  • Given a path, search all children (1 level deep) for a less folder.
  • If the folder is found add the full path as a key to an array
  • Set the value for the key to be the same path, but replace less with css
  • Inside the less directory recursively loop all child directories
  • Add the sub directories in the same manner as the original directories

So, given this structure

Note: All items below except for randomfile are directories

matthew@vaio:/var/www/constructor/public/bundles$ tree
.
├── first
│   └── less
│       ├── secondtester
│       └── tester
│           ├── anothersubtester
│           ├── randomfile
│           └── subtester
├── second
│   └── less
│       ├── secondtester
│       └── tester
│           ├── anothersubtester
│           ├── randomfile
│           └── subtester
└── third
    └── noless
        ├── secondtester
        └── tester
            ├── anothersubtester
            ├── randomfile
            └── subtester

18 directories, 3 files

I want to end up with this array (note I have truncated the path here just to make it easier to read)

Array
    (
    [/b/second/less] => /b/second/css
    [/b/second/less/secondtester] => /b/second/css/secondtester
    [/b/second/less/tester] => /b/second/css/tester
    [/b/second/less/tester/subtester] => /b/second/css/tester/subtester
    [/b/second/less/tester/anothersubtester] => /b/second/css/tester/anothersubtester
    [/b/first/less] => /b/first/css
    [/b/first/less/secondtester] => /b/first/css/secondtester
    [/b/first/less/tester] => /b/first/css/tester
    [/b/first/less/tester/subtester] => /b/first/css/tester/subtester
    [/b/first/less/tester/anothersubtester] => /b/first/css/tester/anothersubtester
)

Now I have the below code, but I don't think this is optimized at all, eg I know there are the RecursiveIteratorIterators etc, but I cannot work out how to use them for this task, so have had to resort to a recursive function that does the lifting. Basically, I am wondering how I could write this to be optimized better:

$directories = array();
$bundlePath = realpath('/public/bundles');

function lessSearcher($lessPath, $cssPath){
    $directories = array($lessPath => $cssPath);

    $lessDirs = new DirectoryIterator($lessPath);
    foreach ($lessDirs as $lessDir) {
        //we only want the directories and not the .'s
        if ($lessDir->isDot() || !$lessDir->isDir()) continue;
        $lessCurrent = $lessPath . '/' . $lessDir->getFileName();
        $cssCurrent = $cssPath . '/' . $lessDir->getFileName();
        $directories[$lessCurrent] = $cssCurrent;
        $directories = array_merge($directories, lessSearcher($lessCurrent, $cssCurrent));
    }

    return $directories;
}

$bundles = new DirectoryIterator($bundlePath);
foreach ($bundles as $bundle) {
    //we only want the directories and not the .'s
    if($bundle->isDot() || !$bundle->isDir()) continue;
    //we only want the directories that have a less directory
    if(!realpath($bundlePath.'/'.$bundle->getFileName().'/less')) continue;

    $lessPath = realpath($bundlePath . '/' . $bundle->getFileName()) . '/less';
    $cssPath = realpath($bundlePath . '/' . $bundle->getFileName()) . '/css';

    $directories = array_merge($directories, lessSearcher($lessPath, $cssPath));
}

I think the code is correctly optimized.
I made a script that lists all the directories and sub-directories and then removes the ones that doesn't have the 'less' directory and creates a new array for the ones that do have it.
Then I tested both yours and mine with a loop of 1000 times. Your script took an average of 0.93s and my script took 1.27s . So in my opinion, your code is okay.

I'd have to say that if its fast enough and does the job then I'd say there's no need to optimize further. If you reach a point that it isn't fast enough or doesn't do the job then revist it then. The recursive iterator isn't likely to do much different to your implementation at any rate.

Sorry I couldn't help more.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM