PHP获取文件列表,包括子目录

时间:2022-09-02 00:22:16

I am trying to retrieve all images in a directory, including all subdirectories. I am currently using

我试图检索目录中的所有图像,包括所有子目录。我目前正在使用

$images = glob("{images/portfolio/*.jpg,images/portfolio/*/*.jpg,images/portfolio/*/*/*.jpg,images/portfolio/*/*/*/*.jpg}",GLOB_BRACE);

This works, however the results are:

这有效,但结果如下:

images/portfolio/1.jpg
images/portfolio/2.jpg
images/portfolio/subdirectory1/1.jpg
images/portfolio/subdirectory1/2.jpg
images/portfolio/subdirectory2/1.jpg
images/portfolio/subdirectory2/2.jpg
images/portfolio/subdirectory1/subdirectory1/1.jpg
images/portfolio/subdirectory1/subdirectory1/2.jpg

I want it to do a whole directory branch at a time so the results are:

我希望它一次做一个完整的目录分支,结果如下:

images/portfolio/1.jpg
images/portfolio/2.jpg
images/portfolio/subdirectory1/1.jpg
images/portfolio/subdirectory1/2.jpg
images/portfolio/subdirectory1/subdirectory1/1.jpg
images/portfolio/subdirectory1/subdirectory1/2.jpg
images/portfolio/subdirectory2/1.jpg
images/portfolio/subdirectory2/2.jpg

Greatly appreciate any help, cheers!

非常感谢任何帮助,欢呼!

P.S It would also be great if I could just get all subdirectories under portfolio without having to specifically state each directory with a wild card.

P.S如果我可以将所有子目录都放在投资组合下而不必使用外卡明确说明每个目录,这也会很棒。

5 个解决方案

#1


25  

from glob example

来自glob示例

if ( ! function_exists('glob_recursive'))
{
    // Does not support flag GLOB_BRACE        
   function glob_recursive($pattern, $flags = 0)
   {
     $files = glob($pattern, $flags);
     foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir)
     {
       $files = array_merge($files, glob_recursive($dir.'/'.basename($pattern), $flags));
     }
     return $files;
   }
}

#2


12  

Solution (change the foldername):

解决方案(更改foldername):

<?php
$path = realpath('yourfolder/examplefolder');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename)
{
        echo "$filename</br>";
}
?>

#3


3  

Here's a simpler approach:

这是一个更简单的方法:

Instead of using:

而不是使用:

$path = realpath('yourfolder/examplefolder/*');
glob($path);

You'll have to use:

你必须使用:

$path = realpath('yourfolder/examplefolder').'/{**/*,*}';
glob($path, GLOB_BRACE);

This last one will use bracing, and it is, in fact, a shorthand for this code:

最后一个将使用支撑,实际上它是此代码的简写:

$path = realpath('yourfolder/examplefolder');

$self_files = glob($path . '/*');
$recursive_files = glob($path . '/**/*');

$all_files = $self_files + $recursive_files; // That's the result you want

You may also want to filter directories from your result. glob() function has GLOB_ONLYDIR flag. Let's use it to diff out our result.

您可能还希望从结果中过滤目录。 glob()函数有GLOB_ONLYDIR标志。让我们用它来区分我们的结果。

$path =  realpath('yourfolder/examplefolder/') . '{**/*,*}';

$all_files = array_diff(
  glob($path, GLOB_BRACE),
  glob($path, GLOB_BRACE | GLOB_ONLYDIR)
);

#4


0  

This function supports GLOB_BRACE:

此函数支持GLOB_BRACE:

function rglob($pattern_in, $flags = 0) {
    $patterns = array ();
    if ($flags & GLOB_BRACE) {
        $matches;
        if (preg_match_all ( '#\{[^.\}]*\}#i', $pattern_in, $matches )) {
            // Get all GLOB_BRACE entries.
            $brace_entries = array ();
            foreach ( $matches [0] as $index => $match ) {
                $brace_entries [$index] = explode ( ',', substr ( $match, 1, - 1 ) );
            }

            // Create cartesian product.
            // @source: https://*.com/questions/6311779/finding-cartesian-product-with-php-associative-arrays
            $cart = array (
                    array () 
            );
            foreach ( $brace_entries as $key => $values ) {
                $append = array ();
                foreach ( $cart as $product ) {
                    foreach ( $values as $item ) {
                        $product [$key] = $item;
                        $append [] = $product;
                    }
                }
                $cart = $append;
            }

            // Create multiple glob patterns based on the cartesian product.
            foreach ( $cart as $vals ) {
                $c_pattern = $pattern_in;
                foreach ( $vals as $index => $val ) {
                    $c_pattern = preg_replace ( '/' . $matches [0] [$index] . '/', $val, $c_pattern, 1 );
                }
                $patterns [] = $c_pattern;
            }
        } else
            $patterns [] = $pattern_in;
    } else
        $patterns [] = $pattern_in;

    // @source: http://php.net/manual/en/function.glob.php#106595
    $result = array ();
    foreach ( $patterns as $pattern ) {
        $files = glob ( $pattern, $flags );
        foreach ( glob ( dirname ( $pattern ) . '/*', GLOB_ONLYDIR | GLOB_NOSORT ) as $dir ) {
            $files = array_merge ( $files, rglob ( $dir . '/' . basename ( $pattern ), $flags ) );
        }
        $result = array_merge ( $result, $files );
    }
    return $result;
}

#5


0  

Simple class:

简单的课程:

<?php
    class AllFiles {
        public $files = [];
        function __construct($folder) {
            $this->read($folder);           
        }
        function read($folder) {
            $folders = glob("$folder/*", GLOB_ONLYDIR);
            foreach ($folders as $folder) {
                $this->files[] = $folder . "/";
                $this->read( $folder );
            }
            $files = array_filter(glob("$folder/*"), 'is_file');
            foreach ($files as $file) {
                $this->files[] = $file;             
            }
        }
        function __toString() {
            return implode( "\n", $this->files );
        }
    };

    $allfiles = new AllFiles("baseq3");
    echo $allfiles;

Example output:

输出示例:

baseq3/gfx/
baseq3/gfx/2d/
baseq3/gfx/2d/numbers/
baseq3/gfx/2d/numbers/eight_32b.tga
baseq3/gfx/2d/numbers/five_32b.tga
baseq3/gfx/2d/numbers/four_32b.tga
baseq3/gfx/2d/numbers/minus_32b.tga
baseq3/gfx/2d/numbers/nine_32b.tga

If you don't want the folders in the list, just comment this line out:

如果您不想要列表中的文件夹,只需注释掉该行:

$this->files[] = $folder . "/";

#1


25  

from glob example

来自glob示例

if ( ! function_exists('glob_recursive'))
{
    // Does not support flag GLOB_BRACE        
   function glob_recursive($pattern, $flags = 0)
   {
     $files = glob($pattern, $flags);
     foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir)
     {
       $files = array_merge($files, glob_recursive($dir.'/'.basename($pattern), $flags));
     }
     return $files;
   }
}

#2


12  

Solution (change the foldername):

解决方案(更改foldername):

<?php
$path = realpath('yourfolder/examplefolder');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename)
{
        echo "$filename</br>";
}
?>

#3


3  

Here's a simpler approach:

这是一个更简单的方法:

Instead of using:

而不是使用:

$path = realpath('yourfolder/examplefolder/*');
glob($path);

You'll have to use:

你必须使用:

$path = realpath('yourfolder/examplefolder').'/{**/*,*}';
glob($path, GLOB_BRACE);

This last one will use bracing, and it is, in fact, a shorthand for this code:

最后一个将使用支撑,实际上它是此代码的简写:

$path = realpath('yourfolder/examplefolder');

$self_files = glob($path . '/*');
$recursive_files = glob($path . '/**/*');

$all_files = $self_files + $recursive_files; // That's the result you want

You may also want to filter directories from your result. glob() function has GLOB_ONLYDIR flag. Let's use it to diff out our result.

您可能还希望从结果中过滤目录。 glob()函数有GLOB_ONLYDIR标志。让我们用它来区分我们的结果。

$path =  realpath('yourfolder/examplefolder/') . '{**/*,*}';

$all_files = array_diff(
  glob($path, GLOB_BRACE),
  glob($path, GLOB_BRACE | GLOB_ONLYDIR)
);

#4


0  

This function supports GLOB_BRACE:

此函数支持GLOB_BRACE:

function rglob($pattern_in, $flags = 0) {
    $patterns = array ();
    if ($flags & GLOB_BRACE) {
        $matches;
        if (preg_match_all ( '#\{[^.\}]*\}#i', $pattern_in, $matches )) {
            // Get all GLOB_BRACE entries.
            $brace_entries = array ();
            foreach ( $matches [0] as $index => $match ) {
                $brace_entries [$index] = explode ( ',', substr ( $match, 1, - 1 ) );
            }

            // Create cartesian product.
            // @source: https://*.com/questions/6311779/finding-cartesian-product-with-php-associative-arrays
            $cart = array (
                    array () 
            );
            foreach ( $brace_entries as $key => $values ) {
                $append = array ();
                foreach ( $cart as $product ) {
                    foreach ( $values as $item ) {
                        $product [$key] = $item;
                        $append [] = $product;
                    }
                }
                $cart = $append;
            }

            // Create multiple glob patterns based on the cartesian product.
            foreach ( $cart as $vals ) {
                $c_pattern = $pattern_in;
                foreach ( $vals as $index => $val ) {
                    $c_pattern = preg_replace ( '/' . $matches [0] [$index] . '/', $val, $c_pattern, 1 );
                }
                $patterns [] = $c_pattern;
            }
        } else
            $patterns [] = $pattern_in;
    } else
        $patterns [] = $pattern_in;

    // @source: http://php.net/manual/en/function.glob.php#106595
    $result = array ();
    foreach ( $patterns as $pattern ) {
        $files = glob ( $pattern, $flags );
        foreach ( glob ( dirname ( $pattern ) . '/*', GLOB_ONLYDIR | GLOB_NOSORT ) as $dir ) {
            $files = array_merge ( $files, rglob ( $dir . '/' . basename ( $pattern ), $flags ) );
        }
        $result = array_merge ( $result, $files );
    }
    return $result;
}

#5


0  

Simple class:

简单的课程:

<?php
    class AllFiles {
        public $files = [];
        function __construct($folder) {
            $this->read($folder);           
        }
        function read($folder) {
            $folders = glob("$folder/*", GLOB_ONLYDIR);
            foreach ($folders as $folder) {
                $this->files[] = $folder . "/";
                $this->read( $folder );
            }
            $files = array_filter(glob("$folder/*"), 'is_file');
            foreach ($files as $file) {
                $this->files[] = $file;             
            }
        }
        function __toString() {
            return implode( "\n", $this->files );
        }
    };

    $allfiles = new AllFiles("baseq3");
    echo $allfiles;

Example output:

输出示例:

baseq3/gfx/
baseq3/gfx/2d/
baseq3/gfx/2d/numbers/
baseq3/gfx/2d/numbers/eight_32b.tga
baseq3/gfx/2d/numbers/five_32b.tga
baseq3/gfx/2d/numbers/four_32b.tga
baseq3/gfx/2d/numbers/minus_32b.tga
baseq3/gfx/2d/numbers/nine_32b.tga

If you don't want the folders in the list, just comment this line out:

如果您不想要列表中的文件夹,只需注释掉该行:

$this->files[] = $folder . "/";