简体   繁体   中英

using glob to return a list of folders in a given directory (without paths)

The function below returns all folders in a given directory down to multiple levels.

I only need one level depth though, just folders in the target directory, no subfolders.

Also the function returns the full path to the folder, I only want the folder name. I'm sure I'm missing something simple.

How can I modify the function to return only the folder names of the given directory? (not the full paths to each folder)

$myArray = get_dirs('../wp-content/themes/mytheme/images');

<?php
  function get_dirs( $path = '.' ){
    return glob( 
      '{' . 
        $path . '/*,'    . # Current Dir
        $path . '/*/*,'  . # One Level Down
        $path . '/*/*/*' . # Two Levels Down, etc.
      '}', GLOB_BRACE + GLOB_ONLYDIR );
  }
?>

btw, thanks to Doug for the original function help!

Instead of using glob() , I would suggest using the DirectoryIterator class.

function get_dirs($path = '.') {
    $dirs = array();

    foreach (new DirectoryIterator($path) as $file) {
        if ($file->isDir() && !$file->isDot()) {
            $dirs[] = $file->getFilename();
        }
    }

    return $dirs;
}

In case you only want the current folder name and have a flat array in return, you can extend a RecursiveFilterIterator and simply collect a stack during RunTime when checking if you want to accept() it. Inside the accept() method you of course skip everything that has no child iterators attached, so you don't unnecessarily traverse through unneeded parts.

class DirectoryStackIterator extends RecursiveFilterIterator
{
    public static $stack = [];

    public function __construct( FilesystemIterator $iterator )
    {
        parent::__construct( $iterator );
    }

    public function getStack()
    {
        return self::$stack;
    }

    public function accept()
    {
        if ( $this->hasChildren() )
        {
            foreach ( $this->getChildren() as $c )
            {
                $dir = basename( $c->getPath() );
                $c->isDir()
                && ! in_array( $dir, self::$stack )
                    AND self::$stack[] = $dir;
            }
        }

        return $this->hasChildren();
    }
}

This makes it quite easy to define what exactly you want in return. $c is an instance of SPLFileInfo , so simply refer to that.

$iterator = new DirectoryStackIterator(
    new RecursiveDirectoryIterator(
        __DIR__,
        FilesystemIterator::FOLLOW_SYMLINKS
        | FilesystemIterator::SKIP_DOTS
    )
);

Then we attach a RecursiveDirectoryIterator (which extends FilesystemIterator , which then extends DirectoryIterator - to see what methods you got) and SKIP_DOTS , but follow symlinks. Remove the later one if you don't want that.

Finally we just traverse through our iterator iterators without actually doing anything. Keep in mind to use a semicolon ( ; ) at the end to not trigger anything on the next line per accident.

foreach ( $iterator as $dir );

Collecting our custom stack then is quite easy:

var_dump( $iterator->getStack() );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM