PHP Récupère tous les sous-répertoires d'un répertoire donné

139

Comment puis-je obtenir tous les sous-répertoires d'un répertoire donné sans fichiers, .(répertoire courant) ou ..(répertoire parent) puis utiliser chaque répertoire dans une fonction?

Adrian M.
la source

Réponses:

210

vous pouvez utiliser glob () avec GLOB_ONLYDIRoption

ou

$dirs = array_filter(glob('*'), 'is_dir');
print_r( $dirs);
ghostdog74
la source
qui donne aussi des sous-répertoires?
Gordon
2
Vous devez faire une resursion ici
Josef Sábl
Désolé, où est l'option GLOB_ONLYDIR ici ??
developerbmw
5
@developerbmw Notez le mot ou . Il présente deux méthodes différentes pour atteindre le but.
Ken Wayne VanderLinde
7
Bien qu'une approche simple et agréable, la réponse acceptée ne répond pas à la question: obtenir des sous-répertoires à partir du répertoire parent (alias les frères et sœurs du répertoire de travail actuel). Pour ce faire, il faudrait changer le répertoire de travail en répertoire parent.
ryanm
156

Voici comment vous pouvez récupérer uniquement les répertoires avec GLOB:

$directories = glob($somePath . '/*' , GLOB_ONLYDIR);
Coreus
la source
2
Cela inclut également le répertoire principal.
user4951
3
Cela n'inclut pas le répertoire principal dans mon cas (Windows)
marcovtwout
1
Cela n'inclut pas non plus le répertoire principal pour moi sur Mac Linux. Peut-être que cela a à voir avec le chemin utilisé?
Jake
1
Cela inclut également le chemin $somePathdans la sortie
The Godfather
47

La classe Spl DirectoryIterator fournit une interface simple pour afficher le contenu des répertoires du système de fichiers.

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

Presque le même que dans votre question précédente :

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

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

Remplacez strtoupperpar la fonction souhaitée.

Gordon
la source
1
gentil merci! une autre question: comment puis-je séparer uniquement le nom du sous-répertoire du chemin complet?
Adrian M.
@Adrian Veuillez consulter la documentation de l'API que j'ai donnée dans votre autre question. getFilename()renverra uniquement le nom du répertoire.
Gordon du
1
Pour me débarrasser des points, j'ai dû ajouter RecursiveDirectoryIterator::SKIP_DOTScomme deuxième argument au RecursiveDirectoryIteratorconstructeur.
colan
5

Essayez ce 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;
keyur0517
la source
4

Dans le tableau:

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

//accès:

$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

Exemple pour tout montrer:

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
la source
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
la source
2

Vous pouvez essayer cette fonction (PHP 7 requis)

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
la source
1

Bonne façon

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

Inspiré par Laravel

Macbric
la source
1
Cela semble exagéré quand il y a un drapeau GLOB_ONLYDIR, voir php.net/manual/en/function.glob.php
Robert Pounder
0

Voici le code d'une ligne:

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

Répertorier uniquement de manière non récursive

La seule question qui a posé directement cela a été fermée à tort, je dois donc la poser ici.

Il donne également la possibilité de filtrer les répertoires.

/**
 * 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;
}
Théodore R. Smith
la source
-1

Trouvez tous les fichiers PHP de manière récursive. La logique doit être assez simple pour être modifiée et elle vise à être rapide (heu) en évitant les appels de fonction.

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;
}
SilbinaireLoup
la source
La question ne demandait pas de liste de fichiers, ni aucune récursivité. Juste une liste de répertoires dans un répertoire donné.
miken32
Je suis bien conscient. À l'époque, je pense que c'était la meilleure réponse sur Google ou similaire, j'ai donc ajouté ma solution pour ceux qui recherchent une implémentation récursive qui ne fait pas exploser la pile. Je ne vois aucun mal à fournir quelque chose qui puisse être réduit pour résoudre le problème initial.
SilbinaryWolf
-1

Si vous recherchez des solutions de liste de répertoires récursifs. Utilisez le code ci-dessous, j'espère que cela devrait vous aider.

<?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
la source
-1

La fonction récursive suivante renvoie un tableau avec la liste complète des sous-répertoires

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/

Fifi
la source
La question ne demandait pas de récursivité. Juste une liste de répertoires dans un répertoire donné, qui leur a été fournie en 2010.
miken32
-2

Trouvez tous les fichiers et dossiers dans un répertoire spécifié.

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

Échantillon :

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
la source
Ce n'est pas une réponse complète, car elle ne peut pas être exécutée.
miken32
@ miken32 C'est une réponse complète, réessayer
A-312