PHP Ottieni tutte le sottodirectory di una determinata directory


139

Come posso ottenere tutte le sottodirectory di una determinata directory senza file, .(directory corrente) o ..(directory principale) e quindi utilizzare ciascuna directory in una funzione?

Risposte:


210

puoi usare glob () con l' GLOB_ONLYDIRopzione

o

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

che dà anche sottodirectory?
Gordon,

2
Devi fare una resurrezione qui
Josef Sábl il

Spiacenti, dov'è l'opzione GLOB_ONLYDIR qui ??
Developerbmw

5
@developerbmw Nota la parola o . Presenta due diversi metodi per raggiungere l'obiettivo.
Ken Wayne VanderLinde

7
Sebbene sia un approccio semplice e gradevole, la risposta accettata non risponde alla domanda: ottenere sottodirectory dalla directory principale (ovvero fratelli della directory di lavoro corrente). Per fare ciò dovrebbe cambiare la directory di lavoro nella directory principale.
Ryanm,

156

Ecco come è possibile recuperare solo le directory con GLOB:

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

2
Ciò include anche la directory principale.
user4951

3
Questo non include la directory principale nel mio caso (Windows)
marcovtwout,

1
Questo non include la directory principale per me su Mac Linux. Forse ha a che fare con il percorso utilizzato?
Jake,

1
Ciò include anche il percorso $somePathnell'output
The Godfather

47

La classe Spl DirectoryIterator fornisce un'interfaccia semplice per visualizzare il contenuto delle directory del filesystem.

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

27

Quasi uguale alla domanda precedente :

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

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

Sostituisci strtouppercon la funzione desiderata.


1
bene grazie! un'altra domanda: come posso separare solo il nome della sottodirectory dall'intero percorso?
Adrian M.

@Adrian Per favore, dai un'occhiata alla documentazione API che ho dato nella tua altra domanda. getFilename()restituirà solo il nome della directory.
Gordon,

1
Per sbarazzarmi dei punti, ho dovuto aggiungere RecursiveDirectoryIterator::SKIP_DOTScome secondo argomento al RecursiveDirectoryIteratorcostruttore.
colan,

5

Prova questo codice:

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

In array:

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

//accesso:

$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

Esempio per mostrare tutto:

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

Puoi provare questa funzione (è richiesto 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

Modo corretto

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

Ispirato da Laravel


1
Questo sembra eccessivo quando c'è una bandiera GLOB_ONLYDIR, vedi php.net/manual/en/function.glob.php
Robert Pounder,

0

Questo è il codice di una riga:

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

0

Elenca solo directory non ricorsive

L'unica domanda diretta è stata questa è stata erroneamente chiusa, quindi devo metterlo qui.

Offre inoltre la possibilità di filtrare le directory.

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

Trova tutti i file PHP in modo ricorsivo. La logica dovrebbe essere abbastanza semplice da modificare e mira ad essere veloce evitando i richiami di funzioni.

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 domanda non ha richiesto un elenco di file o alcuna ricorsione. Solo un elenco di directory in una determinata directory.
miken32,

Sono ben consapevole. Al momento, credo che questa sia stata la risposta migliore su Google o simili, quindi ho aggiunto la mia soluzione per coloro che cercano un'implementazione ricorsiva che non faccia impazzire. Non vedo alcun danno nel fornire qualcosa che può essere ridotto per risolvere il problema originale.
SilbinaryWolf

-1

Se stai cercando una directory ricorsiva che elenca le soluzioni. Usa il codice qui sotto Spero che ti possa aiutare.

<?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 seguente funzione ricorsiva restituisce un array con l'elenco completo delle sottodirectory

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/


La domanda non ha richiesto la ricorsione. Solo un elenco di directory in una determinata directory, che è stata fornita loro nel 2010.
miken32,

-2

Trova tutti i file e le cartelle in una directory specificata.

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

Campione :

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)

Questa non è una risposta completa, in quanto non può essere eseguita.
miken32,

@ miken32 È una risposta completa, riprova
A-312,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.