PHP Obter todos os subdiretórios de um determinado diretório

139

Como posso obter todos os subdiretórios de um determinado diretório sem arquivos .(diretório atual) ou ..(diretório pai) e depois usar cada diretório em uma função?

Adrian M.
fonte

Respostas:

210

você pode usar glob () com a GLOB_ONLYDIRopção

ou

$dirs = array_filter(glob('*'), 'is_dir');
print_r( $dirs);
ghostdog74
fonte
que fornece subdiretórios também?
26710 Gordon
2
Você tem que fazer uma resursão aqui #
Josef Sábl
Desculpe, onde está a opção GLOB_ONLYDIR aqui?
developerbmw
5
@developerbmw Observe a palavra ou . Ele apresenta dois métodos diferentes para atingir a meta.
Ken Wayne Vanderlinde
7
Embora seja uma abordagem simples e agradável, a resposta aceita não responde à pergunta: obter subdiretórios do diretório pai (também conhecidos como irmãos do diretório de trabalho atual). Para fazer isso, seria necessário alterar o diretório de trabalho para o diretório pai.
Ryanm
156

Aqui está como você pode recuperar apenas diretórios com o GLOB:

$directories = glob($somePath . '/*' , GLOB_ONLYDIR);
Coreus
fonte
2
Isso também inclui o diretório principal.
usar o seguinte comando
3
Isso não inclui o diretório principal no meu caso (Windows)
marcovtwout
1
Isso não inclui o diretório principal para mim no mac linux. Talvez tenha a ver com o caminho usado?
Jake
1
Isso inclui também o caminho $somePathna saída
The Godfather
47

A classe Spl DirectoryIterator fornece uma interface simples para visualizar o conteúdo dos diretórios do sistema de arquivos.

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

Quase o mesmo que na sua pergunta anterior :

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

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

Substitua strtoupperpor sua função desejada.

Gordon
fonte
1
bom obrigado! mais uma pergunta: como posso separar apenas o nome do subdiretório de todo o caminho?
Adrian M.
@ Adrian Por favor, dê uma olhada na documentação da API que dei na sua outra pergunta. getFilename()retornará apenas o nome do diretório.
Gordon
1
Para me livrar dos pontos, tive que adicionar RecursiveDirectoryIterator::SKIP_DOTScomo um segundo argumento ao RecursiveDirectoryIteratorconstrutor.
Colan
5

Tente 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;
keyur0517
fonte
4

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

//Acesso:

$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

Exemplo para mostrar tudo:

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
Ricardo Canelas
fonte
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
    */
?>
Sanaan Barzinji
fonte
2

Você pode tentar esta função (requer o 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;
}
Jan-Fokke
fonte
1

A maneira certa

/**
 * 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 pelo Laravel

Macbric
fonte
1
Isso parece um exagero quando há uma bandeira GLOB_ONLYDIR, consulte php.net/manual/en/function.glob.php #
Robert Pounder
0

Este é o código de liner:

 $sub_directories = array_map('basename', glob($directory_path . '/*', GLOB_ONLYDIR));
Sultão
fonte
0

Diretórios não recursivos somente da lista

A única pergunta direta que foi feita foi erroneamente encerrada, então tenho que colocá-lo aqui.

Também oferece a capacidade de filtrar diretórios.

/**
 * 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;
}
Theodore R. Smith
fonte
-1

Encontre todos os arquivos PHP recursivamente. A lógica deve ser simples o suficiente para ajustar e visa ser mais rápida, evitando chamadas de função.

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;
}
SilbinaryWolf
fonte
A pergunta não solicitou uma lista de arquivos ou qualquer recursão. Apenas uma lista de diretórios em um determinado diretório.
Miken32
Eu estou bem ciente. Na época, acredito que essa era a resposta principal no Google ou similar, então adicionei minha solução para quem procura uma implementação recursiva que não explode. Não vejo mal algum em fornecer algo que possa ser diminuído para resolver o problema original.
SilbinaryWolf 13/05/19
-1

Se você está procurando uma lista recursiva de soluções de diretório. Use o código abaixo, espero que ajude você.

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

?>
Faisal
fonte
-1

A seguinte função recursiva retorna uma matriz com a lista completa de subdiretórios

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

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

Fifi
fonte
A pergunta não pediu recursão. Apenas uma lista de diretórios em um determinado diretório, que foi fornecido a eles em 2010.
miken32
-2

Encontre todos os arquivos e pastas em um diretório especificado.

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/'));

Amostra:

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)
A-312
fonte
Esta não é uma resposta completa, pois não pode ser executada.
Miken32
@ miken32 É uma resposta completa, tente novamente
A-312