У меня есть следующая структура каталогов
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
)
)
)
Я пытался использовать RecursiveIteratorIterator
с RecursiveDirectoryIterator
но это дает одноуровневый массив каталогов и файлов, который далек от моего требования. Вот код и результат, который я имею
код
<?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;
}
Результат по печати $ каталогов
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
Таким образом, вы сохраняете возможности «итератора», чтобы делать с ним все остальное. Это часто полезно, когда вы используете итераторы SPL для начала.
Вторая часть, createArray
Функция в основном использует ссылку на массив для указания на «текущий» каталог. Поскольку это будет многомерный массив, нам не нужно беспокоиться о том, «где» в массиве, которым мы на самом деле являемся (это может быть 1-й уровень, это может быть и 100-й уровень, если ваша структура каталогов заходит так глубоко). Он просто проверяет, является ли данный элемент строкой, если это так, то это файл, в противном случае это каталог, поэтому мы рекурсивно вызываем createArray
снова.
Возможно, это более простые решения, но я считаю, что большинство из них использует базовую систему ссылок на массивы.
Других решений пока нет …