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?

Réponses:


210

vous pouvez utiliser glob () avec GLOB_ONLYDIRoption

ou

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

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

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

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.


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;

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

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

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

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


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

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


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

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

?>

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


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)

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.