Как создать массивы подкаталогов с помощью glob

У меня есть следующая структура каталогов:

MainFolder
    Folder1
        Folder1-1
             Folder1-1-1  
             Folder1-1-2
             Folder1-1-3    
        Folder1-2
             Folder1-2-1  
             Folder1-2-2
             Folder1-2-3  
    Folder2
        Folder2-1
             Folder2-1-1  
             Folder2-1-2
             Folder2-1-3  
        Folder2-2
             Folder2-2-1  
             Folder2-2-2
             Folder2-2-3

Я пытаюсь создать 3 массива

1 - массив всех подпапок MainFolder (Folder1, Folder2..etc)

2 - массив подпапок внутри Folder1, Folder2 и т. д. (например, Folder1-1...folder2-1...)

3 - массив подпапок внутри Folder1-1..., Folder1-2... и т.д.

таким образом я могу фильтровать только подкаталоги текущего каталога:

//path to directory to scan
$directory = "MainFolder/";

//get all files in specified directory
$files = glob($directory . "*");

//print each file name
foreach($files as $file)
{
 //check to see if the file is a folder/directory
 if(is_dir($file))
 {
  echo $file;
 }
}

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

Я уже видел, что RecursiveDirectoryIterator существует, но не понял, как его поместить в разные массивы


person Gislef    schedule 24.09.2018    source источник
comment
Возможный дубликат Перечислите все файлы и папки в каталоге с рекурсивной функцией PHP   -  person Madhur Bhaiya    schedule 24.09.2018
comment
@MadhurBhaiya Спасибо, я уже видел этот вопрос, но не смог создать отдельные массивы   -  person Gislef    schedule 24.09.2018
comment
php.net/manual/en/function.glob.php есть комментарий по шаршуну, которые могут вас заинтересовать.   -  person Jhecht    schedule 24.09.2018
comment
@Jhecht спасибо, но в этом случае он создает полностью последовательный массив каталогов и подкаталогов, он не разделяет каталоги на разные массивы, если есть другой массив, это последовательный файл, найденный в папках и подпапках.   -  person Gislef    schedule 24.09.2018
comment
Вам нужно всего 3 массива или вы хотите продолжать как можно дальше?   -  person Barmar    schedule 24.09.2018
comment
@Barmar всего 3 массива   -  person Gislef    schedule 24.09.2018


Ответы (2)


У вас фиксированная низкая глубина, поэтому рекурсивное имхо вам не нужно.

Вы можете использовать подстановочный знак * для обозначения разных уровней и GLOB_ONLYDIR для получения только папок:

$level1 = glob('MainFolder/*', GLOB_ONLYDIR);
$level2 = glob('MainFolder/*/*', GLOB_ONLYDIR);
$level3 = glob('MainFolder/*/*/*', GLOB_ONLYDIR);

Если вы хотите сохранить последнюю папку вместо полного пути, вы можете использовать array_map() и basename():

$level1 = array_map('basename', glob('MainFolder/*', GLOB_ONLYDIR));
...
person JCH77    schedule 24.09.2018

Поместите свой код в функцию, чтобы вы могли вызывать ее для каждого каталога на определенном уровне.

function all_subdirectories($directory) {
    $files = glob("$directory/*");
    return array_filter($files, 'is_dir');
}

Вот код, который создаст двумерный массив для каждого уровня.

$all_levels = array();
$dirs = array("MainFolder");
while (!empty($dirs)) {
    $next_level = array();
    foreach ($dirs as $dir) {
        $next_level += all_subdirectories($dir);
    }
    if (!empty($next_level)) {
        $all_levels[] = array_map('basename', $next_level);
    }
    $dirs = $next_level;
}

print_r($all_levels);

Всего за 3 уровня проще:

$level1 = all_subdirectories("MainFolder");
$level2 = all_subdirectories("MainFolder/*");
$level3 = all_subdirectories("MainFolder/*/*");
person Barmar    schedule 24.09.2018
comment
Спасибо, @Barmar, Parse error: syntax error, unexpected 'in'... Я всегда использовал as в foreach, когда впервые вижу использование in - person Gislef; 24.09.2018
comment
Извините, у меня был Python на мозгу. Пару дней назад я сделал обратное в ответе на Python. - person Barmar; 24.09.2018
comment
:) теперь показывает: Parse error: syntax error, unexpected '{' в строке if (!empty($next_level) { - person Gislef; 24.09.2018
comment
Не хватает скобки, очевидно. - person Barmar; 24.09.2018
comment
отсутствовала только одна )... теперь, похоже, есть ошибка в функции: Warning: array_filter() expects parameter 1 to be array, string given in, относящаяся к части: return array_filter('is_dir', $files);, и другая ошибка Fatal error: Unsupported operand types in, относящаяся к части: $next_level += all_subdirectories($dir); - person Gislef; 24.09.2018
comment
Были аргументы array_filter задом наперед. - person Barmar; 24.09.2018
comment
теперь ошибки нет, но массив пустой: print_r($dirs); результат: Array ( ) - person Gislef; 24.09.2018
comment
Окончательный результат в $all_levels - person Barmar; 24.09.2018
comment
да, я уже пытался print_r($all_levels); это тоже возвращалось пустым - person Gislef; 24.09.2018
comment
Я только что проверил свой код, и он работает. Вы уверены, что указали правильное имя папки в начале $dirs? - person Barmar; 24.09.2018
comment
это сработало отлично, большое спасибо, пришлось еще / указать путь к каталогу - person Gislef; 24.09.2018