Рекурсивный массив структуры каталогов в PHP
Я пытаюсь поместить некоторые папки на мой жесткий диск в массив.
Например, фотографии каникул.
Пусть говорят, что у нас есть эта структура:
- Установить 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]()
Ответы
Ответ 1
Я рекомендую использовать 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;
}
Ответ 2
Простая реализация без обработки ошибок:
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 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 name
$contents[$node] = dirToArray($dir . DIRECTORY_SEPARATOR . $node);
} else {
# Add node, the keys will be updated automatically
$contents[] = $node;
}
}
# done
return $contents;
}
Ответ 3
На основе кода @soulmerge answer. Я просто удалил несколько нит и комментариев и использовал $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);
Ответ 4
У меня был успех с пакетом PEAR File_Find, в частности метод mapTreeMultiple(). Ваш код станет чем-то вроде:
require_once 'File/Find.php';
$fileList = File_Find::mapTreeMultiple($dirPath);
Это должно возвращать массив, аналогичный тому, о котором вы просите.
Ответ 5
Итак, 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 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;
}