PHP 获取给定目录的所有子目录

Posted

技术标签:

【中文标题】PHP 获取给定目录的所有子目录【英文标题】:PHP Get all subdirectories of a given directory 【发布时间】:2011-02-01 05:19:38 【问题描述】:

如何获取给定目录的所有子目录而不包含文件,.(当前目录)或..(父目录) 然后在函数中使用每个目录?

【问题讨论】:

【参考方案1】:

选项 1:

您可以将glob()GLOB_ONLYDIR 选项一起使用。

选项 2:

另一个选项是使用array_filter 过滤目录列表。但是请注意,下面的代码将跳过名称中带有句点的有效目录,例如.config

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

【讨论】:

也提供子目录? 你必须在这里做resursion @developerbmw 注意这个词。他提出了两种不同的实现目标的方法。 虽然是一种不错的简单方法,但公认的答案并没有回答这个问题:从父目录(也就是当前工作目录的同级)获取子目录。为此,需要将工作目录更改为父目录。 这会忽略以点开头的目录,即。 “.config”【参考方案2】:

以下是如何使用 GLOB 仅检索目录:

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

【讨论】:

这也包括主目录。 这不包括我的情况下的主目录(Windows) 这也不包括我在 mac linux 上的主目录。也许它与使用的路径有关? 这还包括输出中的路径$somePath【参考方案3】:

Spl DirectoryIterator 类提供了一个简单的界面来查看文件系统目录的内容。

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

【讨论】:

【参考方案4】:

几乎和你的previous question一样:

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

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

用你想要的函数替换strtoupper

【讨论】:

非常感谢!还有一个问题:如何仅将子目录名称与整个路径分开? @Adrian 请查看我在您的其他问题中提供的 API 文档。 getFilename() 将只返回目录名称。 为了消除这些点,我不得不将RecursiveDirectoryIterator::SKIP_DOTS 作为第二个参数添加到RecursiveDirectoryIterator 构造函数中。【参考方案5】:

在数组中:

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;

//访问:

$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

显示全部示例:

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

【讨论】:

【参考方案6】:

试试这个代码:

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

【讨论】:

【参考方案7】:

你可以试试这个功能(需要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;

【讨论】:

【参考方案8】:
<?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
    */
?>

【讨论】:

【参考方案9】:

非递归仅列出目录

唯一一个direct asked this被错误关闭的问题,所以不得不放在这里。

它还提供了过滤目录的功能。

/**
 * Copyright © 2020 Theodore R. Smith <https://www.phpexperts.pro/>
 * License: MIT
 *
 * @see https://***.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;


【讨论】:

【参考方案10】:

正确的方法

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

受 Laravel 启发

【讨论】:

当有标志 GLOB_ONLYDIR 时,这似乎有点矫枉过正,请参阅 php.net/manual/en/function.glob.php【参考方案11】:

以下递归函数返回一个包含子目录完整列表的数组

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;

来源:https://www.lucidar.me/en/web-dev/how-to-get-subdirectories-in-php/

【讨论】:

问题没有要求递归。只是给定目录中的目录列表,在 2010 年提供给他们。【参考方案12】:

这是单行代码:

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

【讨论】:

【参考方案13】:

您可以使用 glob() 函数来执行此操作。

这里有一些关于它的文档: http://php.net/manual/en/function.glob.php

【讨论】:

【参考方案14】:

递归查找所有 PHP 文件。逻辑应该足够简单以进行调整,并且旨在通过避免函数调用来更快(更)。

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;

【讨论】:

该问题没有要求提供文件列表或任何递归。只是给定目录中的目录列表。 我很清楚。当时,我相信这是 Google 或类似网站上的最佳答案,因此我为那些寻求不会破坏堆栈的递归实现的人添加了我的解决方案。我认为提供可以减少的东西来解决原始问题没有任何害处。【参考方案15】:

如果您正在寻找递归目录列表解决方案。使用下面的代码,希望对您有所帮助。

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

?>

【讨论】:

【参考方案16】:

查找指定目录下的所有文件和文件夹。

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

示例:

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)

【讨论】:

这不是一个完整的答案,因为它无法运行。 @miken32 是完整的答案,重试

以上是关于PHP 获取给定目录的所有子目录的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法从给定路径获取所有子目录? [复制]

Linux 上如何仅获取一级子目录的大小?

如何获取给定目录中的所有文件名

从目录和子目录 php 中获取所有文件、大小、路径

PHP 获取指定目录下所有文件(包含子目录)

PHP 获取指定目录下所有文件(包含子目录)