我正在尝试将硬盘上的一些文件夹放入阵列中。
例如,度假照片。 假设我们有这样的结构:
我希望有这样的东西,作为一个数组 意思是我有一个大数组,在该数组中有更多数组。每个集合和子集都有自己的数组。
我试图让它看起来像这样:
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(...)
...
)
我遇到了这个:http://www.the-art-of-web.com/php/dirlist/
但这不是我想要的。我一直在干涉它,但它只给我带来麻烦。
这是一个示例,查看更大分辨率的源(没有明显点击...)。
答案 0 :(得分:40)
我建议使用DirectoryIterator来构建数组
这是我快速拼凑的片段,但我目前没有测试环境,所以请准备调试它。
$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;
}
答案 1 :(得分:14)
没有任何错误处理的简单实现:
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;
}
答案 2 :(得分:6)
基于@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);
答案 3 :(得分:2)
我在PEAR File_Find包中取得了成功,特别是the mapTreeMultiple() method。您的代码将变为:
require_once 'File/Find.php';
$fileList = File_Find::mapTreeMultiple($dirPath);
这应该返回一个类似于你要求的数组。
答案 4 :(得分:0)
所以6年后....
我需要一个类似@tim&@soulmerge的答案的解决方案。我试图为默认codeigniter文件夹中的所有php文件做批量php UnitTest模板。
这是我过程的第一步,以数组的形式获取目录/文件夹的完整递归内容。然后重新创建文件结构,目录中包含名称正确的文件,类结构,方括号,方法和注释部分,可随时为php UnitTest填充。
总结:给出一个目录名称,将其中所有目录的单层数组作为键,并将其中的所有文件作为值。
我进一步扩展了他们的答案,您将获得以下信息:
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;
}