PHP 获取文件列表,包括子目录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12109042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP get file listing including sub directories
提问by Washburn
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.
PS 如果我可以只获取投资组合下的所有子目录而不必用通配符专门说明每个目录,那也很棒。
回答by diEcho
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;
}
}
回答by T.Todua
Solution:
解决方案:
<?php
$path = realpath('yourfolder/examplefolder');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename)
{
echo "$filename</br>";
}
?>
回答by Andrei Glingeanu
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_ONLYDIRflag. 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)
);
回答by jbenker
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://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;
}
回答by lama12345
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 . "/";

