PHP Obtener todos los subdirectorios de un directorio dado


139

¿Cómo puedo obtener todos los subdirectorios de un directorio dado sin archivos, .(directorio actual) o ..(directorio principal) y luego usar cada directorio en una función?

Respuestas:


210

puedes usar glob () con la GLOB_ONLYDIRopción

o

$dirs = array_filter(glob('*'), 'is_dir');
print_r( $dirs);

que da subdirectorios también?
Gordon

2
Tienes que resurgir aquí
Josef Sábl

Lo sentimos, ¿dónde está la opción GLOB_ONLYDIR aquí?
developerbmw

55
@developerbmw Tenga en cuenta la palabra o . Presenta dos métodos diferentes para alcanzar la meta.
Ken Wayne VanderLinde

77
Si bien es un enfoque simple y agradable, la respuesta aceptada no responde a la pregunta: obtener subdirectorios del directorio principal (también conocido como hermanos del directorio de trabajo actual). Para hacerlo, necesitaría cambiar el directorio de trabajo al directorio principal.
ryanm

156

Así es como puede recuperar solo directorios con GLOB:

$directories = glob($somePath . '/*' , GLOB_ONLYDIR);

2
Esto también incluye el directorio principal.
user4951

3
Esto no incluye el directorio principal en mi caso (Windows)
marcovtwout

1
Esto tampoco incluye el directorio principal para mí en Mac Linux. Tal vez tiene que ver con el camino utilizado?
Jake

1
Esto incluye también el camino $somePathen la salida
The Godfather

47

La clase Spl DirectoryIterator proporciona una interfaz simple para ver el contenido de los directorios del sistema de archivos.

$dir = new DirectoryIterator($path);
foreach ($dir as $fileinfo) {
    if ($fileinfo->isDir() && !$fileinfo->isDot()) {
        echo $fileinfo->getFilename().'<br>';
    }
}

27

Casi lo mismo que en su pregunta anterior :

$iterator = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($yourStartingPath), 
            RecursiveIteratorIterator::SELF_FIRST);

foreach($iterator as $file) {
    if($file->isDir()) {
        echo strtoupper($file->getRealpath()), PHP_EOL;
    }
}

Reemplace strtouppercon su función deseada.


1
¡genial gracias! Una pregunta más: ¿cómo puedo separar solo el nombre del subdirectorio de la ruta completa?
Adrian M.

@Adrian Por favor, eche un vistazo a la documentación API que le di en su otra pregunta. getFilename()solo devolverá el nombre del directorio.
Gordon

1
Para deshacerme de los puntos, tuve que agregar RecursiveDirectoryIterator::SKIP_DOTScomo segundo argumento al RecursiveDirectoryIteratorconstructor.
colan

5

Prueba este código:

<?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;

4

En matriz:

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;
}

//acceso:

$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

Ejemplo para mostrar todo:

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
<?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
    */
?>

2

Puedes probar esta función (se requiere PHP 7)

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;
}

1

Forma apropiada

/**
 * 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);
    });
}

Inspirado por Laravel


1
Esto parece excesivo cuando hay una bandera GLOB_ONLYDIR, ver php.net/manual/en/function.glob.php
Robert Pounder

0

Este es el código único:

 $sub_directories = array_map('basename', glob($directory_path . '/*', GLOB_ONLYDIR));

0

Directorios de lista no recursiva solamente

La única pregunta que hizo directamente esto se ha cerrado erróneamente, así que tengo que ponerla aquí.

También le da la capacidad de filtrar directorios.

/**
 * 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;
}


-1

Encuentra todos los archivos PHP de forma recursiva. La lógica debe ser lo suficientemente simple como para modificarla y pretende ser rápida (er) evitando llamadas a funciones.

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;
}

La pregunta no pedía una lista de archivos, ni ninguna recursividad. Solo una lista de directorios en un directorio dado.
miken32

Estoy bien enterado. En ese momento, creo que esta fue la respuesta principal en Google o similar, así que agregué mi solución para aquellos que buscan una implementación recursiva que no arruine la pila. No veo ningún daño en proporcionar algo que pueda reducirse para resolver el problema original.
SilbinaryWolf

-1

Si está buscando un directorio recursivo con soluciones de listado. Use el siguiente código, espero que le ayude.

<?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>'

?>

-1

La siguiente función recursiva devuelve una matriz con la lista completa de subdirectorios

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;
}

Fuente: https://www.lucidar.me/en/web-dev/how-to-get-subdirectories-in-php/


La pregunta no pedía recursividad. Solo una lista de directorios en un directorio dado, que se les proporcionó en 2010.
miken32

-2

Encuentra todos los archivos y carpetas en un directorio específico.

function scanDirAndSubdir($dir, &$fullDir = array()){
    $currentDir = scandir($dir);

    foreach ($currentDir as $key => $val) {
        $realpath = realpath($dir . DIRECTORY_SEPARATOR . $val);
        if (!is_dir($realpath) && $filename != "." && $filename != "..") {
            scanDirAndSubdir($realpath, $fullDir);
            $fullDir[] = $realpath;
        }
    }

    return $fullDir;
}

var_dump(scanDirAndSubdir('C:/web2.0/'));

Muestra:

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)

Esta no es una respuesta completa, ya que no se puede ejecutar.
miken32

@ miken32 Es una respuesta completa, vuelva a intentarlo
A-312
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.