使用 RecursiveDirectoryIterator 创建一个嵌套的子目录数组

Make a nested array of subdirectories using RecursiveDirectoryIterator

我有如下目录结构

test
  directory_in_test
    directory_in_directory_in_test
  directory2_in_test
    directory_in_directory2_in_test
  abc.php
index.php

我正在尝试创建一个函数来提供子目录的多维数组。所需的输出类似于:

[directories] => Array(
    [test] => Array(
        [directory_in_test] => Array(
            [directory_in_directory_in_test] => null
        )
        [directory2_in_test] => Array(
            [directory_in_directory2_in_test] => null
        )      
    )
)

我曾尝试将 RecursiveIteratorIteratorRecursiveDirectoryIterator 一起使用,但它提供了一级目录和文件数组,这与我的要求相去甚远。这是我的代码和结果

代码

<?php
    public function findDirectories($path = '', $like = '')
    {
        $path = (is_dir($path)) ? $path : getcwd();
        $directories = array();
        $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path));
        foreach ($iterator as $directory) {
            if($directory->isDir())
                $directories[] = $directory->getPathName();
        }

        return $directories;
    }

打印 $directories 的结果

Array
(
    [0] => D:\xampp\htdocs\raheelwp\file-resolver\tests\.
    [1] => D:\xampp\htdocs\raheelwp\file-resolver\tests\..
    [2] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory2_in_test\.
    [3] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory2_in_test\..
    [4] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory2_in_test\directory_in_directory2_in_test\.
    [5] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory2_in_test\directory_in_directory2_in_test\..
    [6] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory_in_test\.
    [7] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory_in_test\..
    [8] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory_in_test\direcotry_in_directory_in_test\.
    [9] => D:\xampp\htdocs\raheelwp\file-resolver\tests\directory_in_test\direcotry_in_directory_in_test\..
) 
<?php

$it = new RecursiveDirectoryIterator(".", RecursiveDirectoryIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($it);

$files = new RecursiveArrayIterator(array());
foreach ($it as $fi) {
    $it = $files;
    $dirs = explode('/', $fi->getPath());
    foreach ($dirs as $path) {
        if (isset($it[$path])) {
            $it = $it[$path];
        } else {
            $it[$path] = new RecursiveArrayIterator();
        }
    }

    $it[$fi->getFileName()] = $fi->getFileName();
}



$a = array();
createArray($a, $files);
print_r($a);

function createArray(&$a, $it) {
    foreach ($it as $k => $tmp) {
        if (is_string($tmp)) {
            $a[] = $tmp;
        } else {
            $a[$k] = array();
            createArray($a[$k], $tmp);
        }
    }
}

代码相当简单,分为两部分,尽管它可以很容易地在一个部分中创建。第一部分会将目录拆分为单独的 RecursiveArrayIterators,因此您可以保留 "iterator" 功能来使用它做所有其他事情。当您开始使用 SPL 迭代器时,这通常很有用。

第二部分,createArray函数基本上使用数组引用指向"current"目录。因为它将是一个多维数组,所以我们不必担心实际数组中的 "where" (它可能是第 1 级,如果你的目录结构那么深,它也可能是第 100 级) .它只是检查给定元素是否为字符串,如果是,则为文件,否则为目录,因此我们再次递归调用 createArray

可能是更简单的解决方案,但我认为它们中的大多数仍然使用基本的数组引用系统。