所以我有以下情况。在我的项目文件夹中,我得到了一个'数据'包含.json文件的文件夹。这些.json文件也是嵌套文件夹中的结构。
类似的东西:
/data
/content
/data1.json
/data2.json
/project
/data3.json
我想创建一个递归遍历数据文件夹并将所有.json文件存储在一个多维数组中的函数,这样可以相对轻松地添加静态数据以用于我的项目。所以预期的结果应该是:
$data = array(
'content' => array(
'data1' => <data-from-data1.json>,
'data2' => <data-from-data2.json>
),
'project' => array(
'data3' => <data-from-data3.json>
)
);
更新
我尝试过以下操作,但这只返回第一级:
$data = array();
$directoryArray = scandir('./data');
foreach($directoryArray as $key => $value) {
$data[$key] = $value;
}
有没有一种巧妙的方法来实现这一目标?
答案 0 :(得分:2)
您应该使用RecursiveIteratorIterator。略过某些目录,例如.
和..
。在此脚本循环其他子目录之后。
//just to remove extension filename
function removeExtension($filename){
return preg_replace('/\\.[^.\\s]{3,4}$/', '', $filename);
}
$startpath= 'data';
$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($startpath), RecursiveIteratorIterator::CHILD_FIRST);
$result = [];
foreach ($ritit as $splFileInfo) {
if ($splFileInfo->getFilename() == '.') continue;
if ($splFileInfo->getFilename() == '..') continue;
if ($splFileInfo->isDir()){
$path = [removeExtension($splFileInfo->getFilename()) => []];
}else{
$path = [removeExtension($splFileInfo->getFilename()) => json_decode(file_get_contents($splFileInfo->getPathname(), $splFileInfo->getFilename()))];
}
for ($depth = $ritit->getDepth() - 1; $depth >= 0; $depth--) {
$path = [$ritit->getSubIterator($depth)->current()->getFilename() => $path];
}
$result = array_merge_recursive($result, $path);
}
print_r($result);
我的json文件包含:
结果是:
Array
(
[content] => Array
(
[data1] => stdClass Object
(
[foo] => foo
)
[data2] => stdClass Object
(
[bar] => bar
)
)
[project] => Array
(
[data3] => stdClass Object
(
[foobar] => foobar
)
)
)
答案 1 :(得分:2)
您实际上不必使用RecursiveIteratorIterator
。作为程序员,您应该始终知道如何处理递归数据结构,可能是xml内容,文件夹树或其他。您可以编写递归函数来处理此类任务。
递归函数是调用自身来处理具有多个layers
或dimensions
的数据的函数。
例如,下面的scanFolder
函数用于处理目录的内容,并在遇到子目录时调用自身。
function scanFolder($path)
{
echo "scanning dir: '$path'";
$contents = array_diff(scandir($path), ['.', '..']);
$result = [];
foreach ($contents as $item) {
$fullPath = $path . DIRECTORY_SEPARATOR . $item;
echo "processing '$fullPath'";
// process folder
if (is_dir($fullPath)) {
// process folder contents
$result[$item] = scanFolder($fullPath);
} else {
// for this specific program, you should perform a check here to see if the file is a json
// collect the result
$result[$item] = json_decode(file_get_contents($fullPath));
}
}
return $result;
}
IMO ,这是一种更干净,更有表现力的方式来完成这项任务,我想知道其他人对此声明的看法。
答案 2 :(得分:-2)
我认为您可以使用RecursiveDirectoryIterator
,there is关于此课程的文档。