How can I get all sub-directories of a given directory without files, .
(current directory) or ..
(parent directory)
and then use each directory in a function?

- 6,880
- 16
- 81
- 127

- 7,183
- 15
- 46
- 54
16 Answers
Option 1:
You can use glob()
with the GLOB_ONLYDIR
option.
Option 2:
Another option is to use array_filter
to filter the list of directories. However, note that the code below will skip valid directories with periods in their name like .config
.
$dirs = array_filter(glob('*'), 'is_dir');
print_r($dirs);

- 7,332
- 3
- 48
- 69

- 327,991
- 56
- 259
- 343
-
that gives subdirectories as well? – Gordon Mar 26 '10 at 15:09
-
3You have to do a resursion here – Josef Sábl Nov 18 '10 at 09:31
-
Sorry, where is the GLOB_ONLYDIR option here?? – brettwhiteman Jul 14 '15 at 04:26
-
6@developerbmw Note the word **or**. He presents two different methods of attaining the goal. – Ken Wayne VanderLinde Jan 08 '16 at 19:20
-
8While a nice, simple approach, the accepted answer does not answer the question: getting sub-directories from the parent directory (aka siblings of current working directory). To do so it'd need to change working directory to the parent directory. – ryanm Nov 07 '16 at 20:12
-
2This ignores directories starting with a dot, ie. ".config" – blade Apr 05 '20 at 10:26
-
Where to define the **PATH** for the directory?! `glob(string $pattern, int $flags = 0):` -- Ah, answered below. That should be specified in the answer. – Avatar Jun 16 '22 at 05:46
Here is how you can retrieve only directories with GLOB:
$directories = glob($somePath . '/*' , GLOB_ONLYDIR);

- 25,694
- 7
- 76
- 115

- 5,360
- 3
- 35
- 50
-
2
-
5
-
3This doesn't include the main directory for me on mac linux either. Maybe it has to do with the path used? – Jake Jan 06 '17 at 12:41
-
1
The Spl DirectoryIterator class provides a simple interface for viewing the contents of filesystem directories.
$dir = new DirectoryIterator($path);
foreach ($dir as $fileinfo) {
if ($fileinfo->isDir() && !$fileinfo->isDot()) {
echo $fileinfo->getFilename().'<br>';
}
}

- 46,049
- 7
- 62
- 106

- 1,508
- 1
- 16
- 26
Almost the same as in your previous question:
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($yourStartingPath),
RecursiveIteratorIterator::SELF_FIRST);
foreach($iterator as $file) {
if($file->isDir()) {
echo strtoupper($file->getRealpath()), PHP_EOL;
}
}
Replace strtoupper
with your desired function.
-
1nice thanks! one more question: how can I separate only the sub-dir name from the whole path? – Adrian M. Mar 26 '10 at 15:36
-
@Adrian Please have a look at the API documentation I gave in your other question. `getFilename()` will return only the directory name. – Gordon Mar 26 '10 at 15:56
-
1To get rid of the dots, I had to add `RecursiveDirectoryIterator::SKIP_DOTS` as a second argument to the `RecursiveDirectoryIterator` constructor. – colan Dec 02 '14 at 22:06
In Array:
function expandDirectoriesMatrix($base_dir, $level = 0) {
$directories = array();
foreach(scandir($base_dir) as $file) {
if($file == '.' || $file == '..') continue;
$dir = $base_dir.DIRECTORY_SEPARATOR.$file;
if(is_dir($dir)) {
$directories[]= array(
'level' => $level
'name' => $file,
'path' => $dir,
'children' => expandDirectoriesMatrix($dir, $level +1)
);
}
}
return $directories;
}
//access:
$dir = '/var/www/';
$directories = expandDirectoriesMatrix($dir);
echo $directories[0]['level'] // 0
echo $directories[0]['name'] // pathA
echo $directories[0]['path'] // /var/www/pathA
echo $directories[0]['children'][0]['name'] // subPathA1
echo $directories[0]['children'][0]['level'] // 1
echo $directories[0]['children'][1]['name'] // subPathA2
echo $directories[0]['children'][1]['level'] // 1
Example to show all:
function showDirectories($list, $parent = array())
{
foreach ($list as $directory){
$parent_name = count($parent) ? " parent: ({$parent['name']}" : '';
$prefix = str_repeat('-', $directory['level']);
echo "$prefix {$directory['name']} $parent_name <br/>"; // <-----------
if(count($directory['children'])){
// list the children directories
showDirectories($directory['children'], $directory);
}
}
}
showDirectories($directories);
// pathA
// - subPathA1 (parent: pathA)
// -- subsubPathA11 (parent: subPathA1)
// - subPathA2
// pathB
// pathC

- 2,280
- 26
- 21
Try this code:
<?php
$path = '/var/www/html/project/somefolder';
$dirs = array();
// directory handle
$dir = dir($path);
while (false !== ($entry = $dir->read())) {
if ($entry != '.' && $entry != '..') {
if (is_dir($path . '/' .$entry)) {
$dirs[] = $entry;
}
}
}
echo "<pre>"; print_r($dirs); exit;

- 85
- 2
- 6
You can try this function (PHP 7 required)
function getDirectories(string $path) : array
{
$directories = [];
$items = scandir($path);
foreach ($items as $item) {
if($item == '..' || $item == '.')
continue;
if(is_dir($path.'/'.$item))
$directories[] = $item;
}
return $directories;
}
This is the one liner code:
$sub_directories = array_map('basename', glob($directory_path . '/*', GLOB_ONLYDIR));

- 637
- 6
- 14
Non-recursively List Only Directories
The only question that direct asked this has been erroneously closed, so I have to put it here.
It also gives the ability to filter directories.
/**
* Copyright © 2020 Theodore R. Smith <https://www.phpexperts.pro/>
* License: MIT
*
* @see https://stackoverflow.com/a/61168906/430062
*
* @param string $path
* @param bool $recursive Default: false
* @param array $filtered Default: [., ..]
* @return array
*/
function getDirs($path, $recursive = false, array $filtered = [])
{
if (!is_dir($path)) {
throw new RuntimeException("$path does not exist.");
}
$filtered += ['.', '..'];
$dirs = [];
$d = dir($path);
while (($entry = $d->read()) !== false) {
if (is_dir("$path/$entry") && !in_array($entry, $filtered)) {
$dirs[] = $entry;
if ($recursive) {
$newDirs = getDirs("$path/$entry");
foreach ($newDirs as $newDir) {
$dirs[] = "$entry/$newDir";
}
}
}
}
return $dirs;
}

- 21,848
- 12
- 65
- 91
<?php
/*this will do what you asked for, it only returns the subdirectory names in a given
path, and you can make hyperlinks and use them:
*/
$yourStartingPath = "photos\\";
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($yourStartingPath),
RecursiveIteratorIterator::SELF_FIRST);
foreach($iterator as $file) {
if($file->isDir()) {
$path = strtoupper($file->getRealpath()) ;
$path2 = PHP_EOL;
$path3 = $path.$path2;
$result = end(explode('/', $path3));
echo "<br />". basename($result );
}
}
/* best regards,
Sanaan Barzinji
Erbil
*/
?>

- 4,738
- 23
- 27
- 42

- 57
- 1
Proper way
/**
* Get all of the directories within a given directory.
*
* @param string $directory
* @return array
*/
function directories($directory)
{
$glob = glob($directory . '/*');
if($glob === false)
{
return array();
}
return array_filter($glob, function($dir) {
return is_dir($dir);
});
}
Inspired by Laravel

- 472
- 4
- 10
-
1This seems overkill when there is a flag `GLOB_ONLYDIR`, see http://php.net/manual/en/function.glob.php – Robert Pounder Dec 05 '16 at 16:42
The following recursive function returns an array with the full list of sub directories
function getSubDirectories($dir)
{
$subDir = array();
$directories = array_filter(glob($dir), 'is_dir');
$subDir = array_merge($subDir, $directories);
foreach ($directories as $directory) $subDir = array_merge($subDir, getSubDirectories($directory.'/*'));
return $subDir;
}
Source: https://www.lucidar.me/en/web-dev/how-to-get-subdirectories-in-php/

- 3,360
- 2
- 27
- 53
-
The question did not ask for recursion. Just a list of directories in a given directory, which was provided to them in 2010. – miken32 May 07 '19 at 15:56
You can use the glob() function to do this.
Here is some documentation on it: http://php.net/manual/en/function.glob.php

- 374
- 2
- 4
- 17
Find all PHP files recursively. The logic should be simple enough to tweak and it aims to be fast(er) by avoiding function calls.
function get_all_php_files($directory) {
$directory_stack = array($directory);
$ignored_filename = array(
'.git' => true,
'.svn' => true,
'.hg' => true,
'index.php' => true,
);
$file_list = array();
while ($directory_stack) {
$current_directory = array_shift($directory_stack);
$files = scandir($current_directory);
foreach ($files as $filename) {
// Skip all files/directories with:
// - A starting '.'
// - A starting '_'
// - Ignore 'index.php' files
$pathname = $current_directory . DIRECTORY_SEPARATOR . $filename;
if (isset($filename[0]) && (
$filename[0] === '.' ||
$filename[0] === '_' ||
isset($ignored_filename[$filename])
))
{
continue;
}
else if (is_dir($pathname) === TRUE) {
$directory_stack[] = $pathname;
} else if (pathinfo($pathname, PATHINFO_EXTENSION) === 'php') {
$file_list[] = $pathname;
}
}
}
return $file_list;
}

- 461
- 4
- 9
-
The question did not ask for a list of files, or any recursion. Just a list of directories in a given directory. – miken32 May 07 '19 at 15:57
-
I'm well-aware. At the time, I believe this was the top-answer on Google or similar, so I added my solution for those looking for a recursive implementation that doesn't blow the stack. I don't see any harm in providing something that can be cut down to solve the original problem. – SilbinaryWolf May 13 '19 at 05:05
If you're looking for a recursive directory listing solutions. Use below code I hope it should help you.
<?php
/**
* Function for recursive directory file list search as an array.
*
* @param mixed $dir Main Directory Path.
*
* @return array
*/
function listFolderFiles($dir)
{
$fileInfo = scandir($dir);
$allFileLists = [];
foreach ($fileInfo as $folder) {
if ($folder !== '.' && $folder !== '..') {
if (is_dir($dir . DIRECTORY_SEPARATOR . $folder) === true) {
$allFileLists[$folder . '/'] = listFolderFiles($dir . DIRECTORY_SEPARATOR . $folder);
} else {
$allFileLists[$folder] = $folder;
}
}
}
return $allFileLists;
}//end listFolderFiles()
$dir = listFolderFiles('your searching directory path ex:-F:\xampp\htdocs\abc');
echo '<pre>';
print_r($dir);
echo '</pre>'
?>

- 4,591
- 3
- 40
- 49
Find all subfolders under a specified directory.
<?php
function scanDirAndSubdir($dir, &$fullDir = array()){
$currentDir = scandir($dir);
foreach ($currentDir as $key => $filename) {
$realpath = realpath($dir . DIRECTORY_SEPARATOR . $filename);
if (!is_dir($realpath) && $filename != "." && $filename != "..") {
scanDirAndSubdir($realpath, $fullDir);
} else {
$fullDir[] = $realpath;
}
}
return $fullDir;
}
var_dump(scanDirAndSubdir('C:/web2.0/'));
Sample :
array (size=4)
0 => string 'C:/web2.0/config/' (length=17)
1 => string 'C:/web2.0/js/' (length=13)
2 => string 'C:/web2.0/mydir/' (length=16)
3 => string 'C:/web2.0/myfile/' (length=17)

- 12,494
- 5
- 50
- 73