递归爬网数据文件夹并创建多维数组

时间:2017-01-16 22:21:07

标签: php arrays json recursion multidimensional-array

所以我有以下情况。在我的项目文件夹中,我得到了一个'数据'包含.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;
}

有没有一种巧妙的方法来实现这一目标?

3 个答案:

答案 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文件包含:

  • data1.json:{“foo”:“foo”}
  • data2.json:{“bar”:“bar”}
  • data3.json:{“foobar”:“foobar”}

结果是:

Array
(
    [content] => Array
        (
            [data1] => stdClass Object
                (
                    [foo] => foo
                )

            [data2] => stdClass Object
                (
                    [bar] => bar
                )

        )

    [project] => Array
        (
            [data3] => stdClass Object
                (
                    [foobar] => foobar
                )

        )

)

答案 1 :(得分:2)

您实际上不必使用RecursiveIteratorIterator。作为程序员,您应该始终知道如何处理递归数据结构,可能是xml内容,文件夹树或其他。您可以编写递归函数来处理此类任务。

递归函数是调用自身来处理具有多个layersdimensions的数据的函数。 例如,下面的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)

我认为您可以使用RecursiveDirectoryIteratorthere is关于此课程的文档。