php PHP中目录结构的深度递归数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/952263/
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
Deep recursive array of directory structure in PHP
提问by KdgDev
I'm trying to put some folders on my hard-drive into an array.
我正在尝试将硬盘驱动器上的一些文件夹放入一个数组中。
For instance, vacation pictures. Let's say we have this structure:
例如,假期照片。假设我们有这样的结构:
- Set 1
- Item 1 of Set 1
- Item 2 of Set 1
- Item ... of Set 1
- Set 2
- Subset 1 of Set 2
- Item 1 of Subset 1 of Set 2
- Item ... of Subset 1 of Set 2
- Subset 2 of Set 2
- Random file, not a dir.
- Subset 1 of Set 2
- Set 3
- ...
- 设置 1
- 第 1 组第 1 项
- 第 1 组第 2 项
- 第 1 组的项目...
- 2套
- 第 2 组的第 1 子集
- 第 2 组第 1 子集的第 1 项
- 第 2 组第 1 子集的项目 ...
- 组 2 的子组 2
- 随机文件,而不是目录。
- 第 2 组的第 1 子集
- 设置 3
- ...
I want to have something like that, as an array.
Meaning I have 1 big array and in that array are more arrays. Each set and subset gets its own array.
我想要这样的东西,作为一个数组。
这意味着我有 1 个大数组,并且该数组中有更多数组。每个集合和子集都有自己的数组。
I'm trying to make it look something like this:
我试图让它看起来像这样:
Array
(
[Set 1] => Array([0] => Item 1 of Set 1, [1] => Item 1 of Set 1,...)
[Set 2] => Array([Subnet 1] => Array([0] => Item 1 of Subset 1 of Set 2,[1] => ...), [Subnet 2] => Array([0] => ..., ..., ...), ..., [0] => Random File)
[set 3] => Array(...)
...
)
I came across this: http://www.the-art-of-web.com/php/dirlist/
我遇到了这个:http: //www.the-art-of-web.com/php/dirlist/
But that's not what I'm looking for. I've been meddling with it but it's giving me nothing but trouble.
但这不是我要找的。我一直在干预它,但它给我带来的只是麻烦。
Here's an example, view source for larger resolution(no clicking apparently...).

这是一个示例,查看更大分辨率的源代码(显然没有点击......)。

回答by Peter Bailey
I recommend using DirectoryIteratorto build your array
我建议使用DirectoryIterator来构建数组
Here's a snippet I threw together real quick, but I don't have an environment to test it in currently so be prepared to debug it.
这是我很快拼凑起来的一个片段,但我目前没有一个环境来测试它,所以准备调试它。
$fileData = fillArrayWithFileNodes( new DirectoryIterator( '/path/to/root/' ) );
function fillArrayWithFileNodes( DirectoryIterator $dir )
{
$data = array();
foreach ( $dir as $node )
{
if ( $node->isDir() && !$node->isDot() )
{
$data[$node->getFilename()] = fillArrayWithFileNodes( new DirectoryIterator( $node->getPathname() ) );
}
else if ( $node->isFile() )
{
$data[] = $node->getFilename();
}
}
return $data;
}
回答by soulmerge
A simple implementation without any error handling:
一个没有任何错误处理的简单实现:
function dirToArray($dir) {
$contents = array();
# Foreach node in $dir
foreach (scandir($dir) as $node) {
# Skip link to current and parent folder
if ($node == '.') continue;
if ($node == '..') continue;
# Check if it's a node or a folder
if (is_dir($dir . DIRECTORY_SEPARATOR . $node)) {
# Add directory recursively, be sure to pass a valid path
# to the function, not just the folder's name
$contents[$node] = dirToArray($dir . DIRECTORY_SEPARATOR . $node);
} else {
# Add node, the keys will be updated automatically
$contents[] = $node;
}
}
# done
return $contents;
}
回答by tim
Based on the code of @soulmerge's answer. I just removed some nits and the comments and use $startpathas my starting directory. (THANK YOU @soulmerge!)
基于@soulmerge's answer的代码。我只是删除了一些 nits 和评论并$startpath用作我的起始目录。(谢谢@soulmerge!)
function dirToArray($dir) {
$contents = array();
foreach (scandir($dir) as $node) {
if ($node == '.' || $node == '..') continue;
if (is_dir($dir . '/' . $node)) {
$contents[$node] = dirToArray($dir . '/' . $node);
} else {
$contents[] = $node;
}
}
return $contents;
}
$r = dirToArray($startpath);
print_r($r);
回答by Michael Johnson
I've had success with the PEAR File_Find package, specifically the mapTreeMultiple() method. Your code would become something like:
我已经成功使用 PEAR File_Find 包,特别是 mapTreeMultiple() 方法。你的代码会变成这样:
require_once 'File/Find.php';
$fileList = File_Find::mapTreeMultiple($dirPath);
This should return an array similar to what you're asking for.
这应该返回一个类似于您要求的数组。
回答by modnarrandom
So 6 years later....
所以6年后......
I needed a solution like the answers by @tim & @soulmerge. I was trying to do bulk php UnitTest templates for all of the php files in the default codeigniter folders.
我需要一个解决方案,比如@tim & @soulmerge 的答案。我试图为默认的 codeigniter 文件夹中的所有 php 文件做批量 php UnitTest 模板。
This was step one in my process, to get the full recursive contents of a directory / folder as an array. Then recreate the file structure, and inside the directories have files with the proper name, class structure, brackets, methods and comment sections ready to fill in for the php UnitTest.
这是我过程中的第一步,将目录/文件夹的完整递归内容作为数组获取。然后重新创建文件结构,目录中的文件具有适当的名称、类结构、括号、方法和注释部分,准备为 php UnitTest 填写。
To summarize: give a directory name, get a single layered array of all directories within it as keys and all files within as values.
总结一下:给出一个目录名称,获取其中所有目录作为键和所有文件作为值的单层数组。
I expanded a their answer a bit further and you get the following:
我进一步扩展了他们的答案,您会得到以下信息:
function getPathContents($path)
{
// was a file path provided?
if ($path === null){
// default file paths in codeigniter 3.0
$dirs = array(
'./models',
'./controllers'
);
} else{
// file path was provided
// it can be a comma separated list or singular filepath or file
$dirs = explode(',', $path);
}
// final array
$contents = array();
// for each directory / file given
foreach ($dirs as $dir) {
// is it a directory?
if (is_dir($dir)) {
// scan the directory and for each file inside
foreach (scandir($dir) as $node) {
// skip current and parent directory
if ($node === '.' || $node === '..') {
continue;
} else {
// check for sub directories
if (is_dir($dir . '/' . $node)) {
// recursive check for sub directories
$recurseArray = getPathContents($dir . '/' . $node);
// merge current and recursive results
$contents = array_merge($contents, $recurseArray);
} else {
// it a file, put it in the array if it's extension is '.php'
if (substr($node, -4) === '.php') {
// don'r remove periods if current or parent directory was input
if ($dir === '.' || $dir === '..') {
$contents[$dir][] = $node;
} else {
// remove period from directory name
$contents[str_replace('.', '', $dir)][] = $node;
}
}
}
}
}
} else {
// file name was given
$contents[] = $dir;
}
}
return $contents;
}

