PHP获取包含子目录的文件列表
Posted
技术标签:
【中文标题】PHP获取包含子目录的文件列表【英文标题】:PHP get file listing including sub directories 【发布时间】: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 如果我可以直接获取投资组合下的所有子目录,而不必用通配符具体说明每个目录,那就太好了。
【问题讨论】:
【参考方案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://***.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 . "/";
【讨论】:
以上是关于PHP获取包含子目录的文件列表的主要内容,如果未能解决你的问题,请参考以下文章