【问题标题】:PHP get file listing including sub directoriesPHP获取包含子目录的文件列表
【发布时间】:2012-08-19 23:55:22
【问题描述】:

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

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

这可行,但结果是:

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

我希望它一次做一个完整的目录分支,所以结果是:

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

非常感谢任何帮助,干杯!

P.S 如果我可以直接获取投资组合下的所有子目录,而不必用通配符具体说明每个目录,那就太好了。

【问题讨论】:

    标签: php glob


    【解决方案1】:

    来自glob example

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

    【讨论】:

    • 感谢 diEcho,在发布之前刚刚查看了该页面并完全错过了该示例。干杯!
    【解决方案2】:

    解决方案

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

    【讨论】:

    • 如何处理文件名模式?
    • 首先将它们全部抓取到一个数组中,然后使用 foreach 和 if 语句过滤它们:)
    • glob_recursive 方法以字母顺序返回一个数组,而使用这些递归迭代器以看似随机的顺序返回文件。如果订单有问题,请记住这一点。
    【解决方案3】:

    这里有一个更简单的方法:

    而不是使用:

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

    你必须使用:

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

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

    $path = realpath('yourfolder/examplefolder');
    
    $self_files = glob($path . '/*');
    $recursive_files = glob($path . '/**/*');
    
    $all_files = $self_files + $recursive_files; // That's the result you want
    

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

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

    【讨论】:

    • realpath() 不接受超过 1 个参数,我也不相信它支持 glob 模式。
    • 警告:realpath() 只需要 1 个参数,给定 2 个参数 $path = realpath('yourfolder/examplefolder/{**/*,*}', GLOB_BRACE);glob($path . '/**/*'); 无法递归列出文件和文件夹。
    • 我认为你打错了一些东西。在我的示例中,我们只将一个参数传递给realpath
    • 在第二个示例块中,您将 GLOB_BRACE 作为 realpath 参数传递。
    【解决方案4】:

    此函数支持 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://stackoverflow.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】:

      简单类:

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

      示例输出:

      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
      

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-05
        相关资源
        最近更新 更多