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?

Respostas:


210

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

ou

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

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

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

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.


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;

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

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

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

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


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

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


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

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

?>

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


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)

Esta não é uma resposta completa, pois não pode ser executada.
Miken32

@ miken32 É uma resposta completa, tente novamente
A-312
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.