Глубокий рекурсивный массив структуры каталогов в PHP - PullRequest
18 голосов
/ 04 июня 2009

Я пытаюсь поместить несколько папок на моем жестком диске в массив.

Например, отпускные картинки. Допустим, у нас есть эта структура:

  • Набор 1
    • Позиция 1 из набора 1
    • Пункт 2 из набора 1
    • Предмет ... из набора 1
  • Набор 2
    • Подмножество 1 из набора 2
      • Элемент 1 из подмножества 1 из набора 2
      • Элемент ... подмножества 1 из набора 2
    • Подмножество 2 из набора 2
    • Случайный файл, а не каталог.
  • Набор 3
  • ...

Я хочу иметь что-то подобное в виде массива.
Это означает, что у меня есть 1 большой массив, и в этом массиве больше массивов. Каждый набор и подмножество получает свой собственный массив.

Я пытаюсь, чтобы это выглядело примерно так:

Array
(
    [Set 1] => Array([0] => Item 1 of Set 1, [1] => Item 1 of Set 1,...)
    [Set 2] => Array([Subnet 1] => Array([0] => Item 1 of Subset 1 of Set 2,[1] => ...), [Subnet 2] => Array([0] => ..., ..., ...), ..., [0] => Random File)
    [set 3] => Array(...)
    ...
)

Я сталкивался с этим: http://www.the -art-of-web.com / php / dirlist /

Но это не то, что я ищу. Я вмешивался в это, но это не доставляет мне ничего, кроме неприятностей.

Вот пример, просмотрите источник для большего разрешения (очевидно, не щелкая ...). Example

Ответы [ 5 ]

40 голосов
/ 04 июня 2009

Я рекомендую использовать DirectoryIterator для построения вашего массива

Вот фрагмент, который я собрал очень быстро, но в настоящее время у меня нет среды для его тестирования, поэтому будьте готовы к его отладке.

$fileData = fillArrayWithFileNodes( new DirectoryIterator( '/path/to/root/' ) );

function fillArrayWithFileNodes( DirectoryIterator $dir )
{
  $data = array();
  foreach ( $dir as $node )
  {
    if ( $node->isDir() && !$node->isDot() )
    {
      $data[$node->getFilename()] = fillArrayWithFileNodes( new DirectoryIterator( $node->getPathname() ) );
    }
    else if ( $node->isFile() )
    {
      $data[] = $node->getFilename();
    }
  }
  return $data;
}
14 голосов
/ 04 июня 2009

Простая реализация без обработки ошибок:

function dirToArray($dir) {
    $contents = array();
    # Foreach node in $dir
    foreach (scandir($dir) as $node) {
        # Skip link to current and parent folder
        if ($node == '.')  continue;
        if ($node == '..') continue;
        # Check if it's a node or a folder
        if (is_dir($dir . DIRECTORY_SEPARATOR . $node)) {
            # Add directory recursively, be sure to pass a valid path
            # to the function, not just the folder's name
            $contents[$node] = dirToArray($dir . DIRECTORY_SEPARATOR . $node);
        } else {
            # Add node, the keys will be updated automatically
            $contents[] = $node;
        }
    }
    # done
    return $contents;
}
6 голосов
/ 22 января 2013

На основании кода ответа @ soulmerge . Я просто удалил некоторые гниды и комментарии и использую $startpath в качестве моего начального каталога. (СПАСИБО @Soulmerge!)

function dirToArray($dir) {
    $contents = array();
    foreach (scandir($dir) as $node) {
        if ($node == '.' || $node == '..') continue;
        if (is_dir($dir . '/' . $node)) {
            $contents[$node] = dirToArray($dir . '/' . $node);
        } else {
            $contents[] = $node;
        }
    }
    return $contents;
}

$r = dirToArray($startpath);
print_r($r);
2 голосов
/ 04 июня 2009

У меня был успех с пакетом PEAR File_Find, в частности метод mapTreeMultiple () . Ваш код станет примерно таким:

require_once 'File/Find.php';
$fileList = File_Find::mapTreeMultiple($dirPath);

Это должно вернуть массив, аналогичный тому, который вы запрашиваете.

0 голосов
/ 26 мая 2019

Итак, 6 лет спустя ....

Мне нужно решение, подобное ответам @tim & @soulmerge. Я пытался сделать массовые шаблоны php UnitTest для всех файлов php в папках codeigniter по умолчанию.

Это был первый шаг в моем процессе, чтобы получить полное рекурсивное содержимое каталога / папки в виде массива. Затем воссоздайте структуру файлов, и внутри каталогов есть файлы с правильным именем, структурой классов, скобками, методами и разделами комментариев, готовые для заполнения для php UnitTest.

Подводя итог: дайте имя каталога, получите однослойный массив всех каталогов в нем в виде ключей и всех файлов в качестве значений.

Я расширил их ответ немного дальше, и вы получите следующее:

function getPathContents($path)
{
     // was a file path provided?
     if ($path === null){
        // default file paths in codeigniter 3.0
        $dirs = array(
            './models',
            './controllers'
        );
    } else{
        // file path was provided
        // it can be a comma separated list or singular filepath or file
        $dirs = explode(',', $path);
    }
    // final array
    $contents = array();
    // for each directory / file given
    foreach ($dirs as $dir) {
        // is it a directory?
        if (is_dir($dir)) {
            // scan the directory and for each file inside
            foreach (scandir($dir) as $node) {
                // skip current and parent directory
                if ($node === '.' || $node === '..') {
                    continue;
                } else {
                    // check for sub directories
                    if (is_dir($dir . '/' . $node)) {
                        // recursive check for sub directories
                        $recurseArray = getPathContents($dir . '/' . $node);
                        // merge current and recursive results
                        $contents = array_merge($contents, $recurseArray);
                    } else {
                        // it a file, put it in the array if it's extension is '.php'
                        if (substr($node, -4) === '.php') {
                            // don'r remove periods if current or parent directory was input
                            if ($dir === '.' || $dir === '..') {
                                $contents[$dir][] = $node;
                            } else {
                                // remove period from directory name 
                                $contents[str_replace('.', '', $dir)][] = $node;
                            }
                        }
                    }
                }
            }
        } else {
            // file name was given
            $contents[] = $dir; 
        }
    }
    return $contents;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...