将多个JSON合并到单个对象中

时间:2012-10-07 09:40:38

标签: php arrays json

我有多个JSON文件,我想解析,编辑和合并到一个对象,最终将重新编码并输出为单个JSON。

我目前有一个工作示例,当我解析和编辑一个对象时,但我无法弄清楚如何做两个并得到一个结果。

工作示例:

$source = 'http://www.jakedup.com/_/source1';

$data = json_decode(file_get_contents($source));

// THIS WILL BE THE FINAL OUTPUT OBJECT
$output = new stdClass();

// GET THE ARTICLE DATES AS AN ARRAY
$tracks = get_object_vars($data->tracks);

// LOOPS OVER ARTICLE PUBDATES TO GET THE OUTER OBJECTS
foreach ($tracks as $key=>$val) {
  // LOOPS OVER THE INNER OBJECTS IN EACH ARTICLE PUBDATE
  foreach ($data->tracks->$key as $object) {
    // ADD IT ONTO THE OUTPUT OBJECT WITH "ID" AS PARENT NAME
    $output->{$object->id} = $object;
  }
}

echo json_encode($output);

以下是我的JSON示例。我提供了两个示例,但我正在寻找一种动态合并无限数量的JSON文件的方法。

JSON Source1:

{
    "foo":"bar",
    "tracks":{
        "1349496000":[
            {
                "id":"25328",
                "is_promo":null,
                "is_feature":null,
                "listens":"1312",
                "downloads":"777"
            },
            {
                "id":"25327",
                "is_promo":null,
                "is_feature":null,
                "listens":"1255",
                "downloads":"578"
            },
            {
                "id":"25329",
                "is_promo":null,
                "is_feature":null,
                "listens":"341",
                "downloads":"139"
            }
        ],
        "1349323200":[
            {
                "id":"25310",
                "is_promo":null,
                "is_feature":null,
                "listens":"10793",
                "downloads":"4953"
            }
        ]
    }
}

JSON来源2:

{
    "foo":"bar",
    "tracks":{
        "1349323200":[
            {
                "id":"25303",
                "is_promo":null,
                "is_feature":null,
                "listens":"2347",
                "downloads":"1499"
            }
        ],
        "1349236800":[
            {
                "id":"25266",
                "is_promo":null,
                "is_feature":null,
                "listens":"24485",
                "downloads":"19366"
            }
        ]
    }
}

我一直在寻找在循环中获取源代码的想法,但是当它合并数据时我被困住了。我所有的不同努力都没有产生正确的数据结构。

当前测试代码:

$source = 'http://www.jakedup.com/_/source';
$pages = 2;

    for ($i = 1; $i <= $pages; $i++) {
        $sources[$i] = $source.$i;
        ${'source'.$i} = json_decode(file_get_contents($source.$i));
    }

我现在有两个对象 - $ source1&amp; $ source2 - 但我不知道下一步该做什么。

这是我期待的输出:

{
    "25328": {
        "id": "25328",
        "is_promo": null,
        "is_feature": null,
        "listens": "1312",
        "downloads": "777",
        "timestamp": "1349496000"
    },
    "25327": {
        "id": "25327",
        "is_promo": null,
        "is_feature": null,
        "listens": "1255",
        "downloads": "578",
        "timestamp": "1349496000"
    },
    "25329": {
        "id": "25329",
        "is_promo": null,
        "is_feature": null,
        "listens": "341",
        "downloads": "139",
        "timestamp": "1349496000"
    },
    "25310": {
        "id": "25310",
        "is_promo": null,
        "is_feature": null,
        "listens": "10793",
        "downloads": "4953",
        "timestamp": "1349323200"
    },
    "25303": {
        "id": "25303",
        "is_promo": null,
        "is_feature": null,
        "listens": "2347",
        "downloads": "1499",
        "timestamp": "1349323200"
    },
    "25266": {
        "id": "25266",
        "is_promo": null,
        "is_feature": null,
        "listens": "24485",
        "downloads": "19366",
        "timestamp": "1349236800"
    }
}

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:4)

使用PHP数组更简单一点,而不是尝试使用数字属性构建stdClass对象。如果PHP数组具有非连续的非零键,json_encode()将自动生成对象{}而不是数组[]。同样,json_decode()有一个可选的第二个参数来生成关联数组而不是对象。因此,我建议将文件解码为数组并循环遍历它们,将每个id附加到输出数组上,最后再次json_encode()

您的代码暗示您拥有“http://www.jakedup.com/_/source1”等JSON源文件。您处于正确的轨道上,但不是填充新的变量变量,而是在循环中检索和解码每个文件,并将其直接附加到输出数组。

// 5 source numbers, don't have to be consecutive
$sources = array(1,2,3,4,5);
// Output array to be encoded as JSON
$output = array();

// Loop over all the source files, retrieve them and add tracks onto the output    
foreach ($sources as $sourcenum) {
  $source = "http://www.jakedup.com/_/source$sourcenum";
  $source_json = file_get_contents($source);

  // Decode it as an associative array, passing TRUE as second param
  $source_array = json_decode($source_json, TRUE);

  // Now loop over the tracks (which are an array) and append each to the output
  // the original key looks like a timestamp
  foreach ($source_array['tracks'] as $timestamp => $ts) {
    foreach ($ts as $track) {
      // Add the track id to $output as a key
      // This doesn't check if the id already exists...
      // if it does, it will just be overwritten with this one
      $output[$track['id']] = $track;
      // Optionally, save the original timestamp key into the track array
      // Maybe you don't care about this
      $output[$track['id']]['timestamp'] = $timestamp;
    }
  }
}

// Look over your array
var_dump($output);

// Finally, re-encode the whole thing back to JSON
// using JSON_FORCE_OBJECT (even though it shouldn't be necessary)
$output_json = json_encode($output, JSON_FORCE_OBJECT);

JSON输出:

{
    "25328": {
        "id": "25328",
        "is_promo": null,
        "is_feature": null,
        "listens": "1312",
        "downloads": "777",
        "timestamp": 1349496000
    },
    "25327": {
        "id": "25327",
        "is_promo": null,
        "is_feature": null,
        "listens": "1255",
        "downloads": "578",
        "timestamp": 1349496000
    },
    "25329": {
        "id": "25329",
        "is_promo": null,
        "is_feature": null,
        "listens": "341",
        "downloads": "139",
        "timestamp": 1349496000
    },
    "25310": {
        "id": "25310",
        "is_promo": null,
        "is_feature": null,
        "listens": "10793",
        "downloads": "4953",
        "timestamp": 1349323200
    },
    "25303": {
        "id": "25303",
        "is_promo": null,
        "is_feature": null,
        "listens": "2347",
        "downloads": "1499",
        "timestamp": 1349323200
    },
    "25266": {
        "id": "25266",
        "is_promo": null,
        "is_feature": null,
        "listens": "24485",
        "downloads": "19366",
        "timestamp": 1349236800
    }
}