遍历目录下所有子目录

4
我有一个看起来很简单的任务,
  • 给定一个路径,搜索所有子目录(仅一层)中的 less 目录。
  • 如果找到该目录,则将其完整路径添加为数组的键。
  • 将该键的值设置为相同的路径,但将 less 替换为 css
  • 在 less 目录内递归遍历所有子目录。
  • 像处理原始目录一样添加子目录。

因此,给定以下结构:

注意:下面的所有项(除了 randomfile)都是目录

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

我希望最终得到的是这个数组(请注意,我在此处截断了路径,只是为了更容易阅读)
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
)

现在我有以下代码,但我认为这并不是很优化,例如,我知道有RecursiveIteratorIterators等东西,但我无法想出如何将它们用于此任务,因此不得不使用递归函数来完成。基本上,我想知道如何更好地编写此代码以获得更好的性能:
$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));
}

说实话,我没有看到太多问题,它运行速度还可以吗? - Rob Forrest
是的,它似乎运行得足够快,我只是想使用 RecursiveDirectoryIterator 可能会更好,但是我无法弄清楚如何实际使用它们。 - Hailwood
2个回答

0
我必须说,如果它足够快并且能够完成工作,那么我认为没有必要进一步优化。如果你达到了一个不够快或者不能完成工作的点,那么再回过头来看看它。递归迭代器在任何情况下都不太可能对你的实现产生太大的影响。
很抱歉我帮不上更多的忙。

0

我认为代码已经被正确优化了。
我编写了一个脚本,列出所有目录和子目录,然后删除没有“less”目录的目录,并为具有该目录的目录创建一个新数组。
然后,我使用1000次循环测试了你的脚本和我的脚本。你的脚本平均需要0.93秒,而我的脚本需要1.27秒。所以在我看来,你的代码没问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接