PHP Ruft alle Unterverzeichnisse eines bestimmten Verzeichnisses ab


139

Wie kann ich alle Unterverzeichnisse eines bestimmten Verzeichnisses ohne Dateien .(aktuelles Verzeichnis) oder ..(übergeordnetes Verzeichnis) abrufen und dann jedes Verzeichnis in einer Funktion verwenden?

Antworten:


210

Sie können glob () mit GLOB_ONLYDIROption verwenden

oder

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

das gibt auch Unterverzeichnisse?
Gordon

2
Sie müssen hier eine Exkursion machen
Josef Sábl

Entschuldigung, wo ist die Option GLOB_ONLYDIR hier?
Developerbmw

5
@developerbmw Beachten Sie das Wort oder . Er präsentiert zwei verschiedene Methoden, um das Ziel zu erreichen.
Ken Wayne VanderLinde

7
Obwohl dies ein netter, einfacher Ansatz ist, beantwortet die akzeptierte Antwort nicht die Frage: Abrufen von Unterverzeichnissen aus dem übergeordneten Verzeichnis (auch bekannt als Geschwister des aktuellen Arbeitsverzeichnisses). Dazu müsste das Arbeitsverzeichnis in das übergeordnete Verzeichnis geändert werden.
Ryanm

156

So können Sie mit GLOB nur Verzeichnisse abrufen:

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

2
Dies schließt auch das Hauptverzeichnis ein.
user4951

3
Dies beinhaltet nicht das Hauptverzeichnis in meinem Fall (Windows)
marcovtwout

1
Dies beinhaltet auch nicht das Hauptverzeichnis für mich unter Mac Linux. Vielleicht hat es mit dem verwendeten Pfad zu tun?
Jake

1
Dies schließt auch den Pfad $somePathin der Ausgabe ein
The Godfather

47

Die Spl DirectoryIterator- Klasse bietet eine einfache Schnittstelle zum Anzeigen des Inhalts von Dateisystemverzeichnissen.

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

27

Fast das gleiche wie in Ihrer vorherigen Frage :

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

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

Ersetzen Sie strtoupperdurch Ihre gewünschte Funktion.


1
nett, danke! Noch eine Frage: Wie kann ich nur den Unterverzeichnisnamen vom gesamten Pfad trennen?
Adrian M.

@Adrian Bitte werfen Sie einen Blick auf die API-Dokumentation, die ich in Ihrer anderen Frage gegeben habe. getFilename()gibt nur den Verzeichnisnamen zurück.
Gordon

1
Um die Punkte loszuwerden, musste ich RecursiveDirectoryIterator::SKIP_DOTSdem RecursiveDirectoryIteratorKonstruktor als zweites Argument hinzufügen .
Colan

5

Versuchen Sie diesen 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

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

//Zugriff:

$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

Beispiel, um alle zu zeigen:

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

Sie können diese Funktion ausprobieren (PHP 7 erforderlich)

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

Richtige Weg

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

Inspiriert von Laravel


1
Dies scheint übertrieben, wenn es eine Flagge gibt GLOB_ONLYDIR, siehe php.net/manual/en/function.glob.php
Robert Pounder

0

Dies ist der Einzeiler-Code:

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

0

Nicht rekursiv Nur Verzeichnisse auflisten

Die einzige Frage, die dies direkt stellte wurde, wurde fälschlicherweise geschlossen, daher muss ich sie hier einfügen.

Es gibt auch die Möglichkeit, Verzeichnisse zu filtern.

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

Finden Sie alle PHP-Dateien rekursiv. Die Logik sollte einfach genug sein, um optimiert zu werden, und sie soll schnell (er) sein, indem Funktionsaufrufe vermieden werden.

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

Bei der Frage wurde weder nach einer Liste von Dateien noch nach einer Rekursion gefragt. Nur eine Liste von Verzeichnissen in einem bestimmten Verzeichnis.
miken32

Mir ist klar. Zu der Zeit glaube ich, dass dies die Top-Antwort bei Google oder ähnlichem war. Deshalb habe ich meine Lösung für diejenigen hinzugefügt, die nach einer rekursiven Implementierung suchen, die den Stapel nicht sprengt. Ich sehe keinen Schaden darin, etwas bereitzustellen, das zur Lösung des ursprünglichen Problems reduziert werden kann.
SilbinaryWolf

-1

Wenn Sie nach Lösungen für eine rekursive Verzeichnisliste suchen. Verwenden Sie den folgenden Code. Ich hoffe, er sollte Ihnen helfen.

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

Die folgende rekursive Funktion gibt ein Array mit der vollständigen Liste der Unterverzeichnisse zurück

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

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


Die Frage verlangte keine Rekursion. Nur eine Liste von Verzeichnissen in einem bestimmten Verzeichnis, die ihnen im Jahr 2010 zur Verfügung gestellt wurde.
miken32

-2

Suchen Sie alle Dateien und Ordner in einem angegebenen Verzeichnis.

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

Stichprobe :

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)

Dies ist keine vollständige Antwort, da sie nicht ausgeführt werden kann.
miken32

@ miken32 Es ist eine vollständige Antwort, versuchen Sie es erneut
A-312
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.