我有两个从JSON转换的数据对象。两者都非常复杂,我想以类似的方式将它们合并到jQuery如何使用extend合并两个对象。
例如
JSON 1:
{
...
"blah":
{
"params":
{
"foo":
{
"default": "bar",
"misc": "0",
...
},
...
},
...
},
...
}
JSON 2:
{
...
"blah":
{
"params":
{
"foo":
{
"value": "val",
"misc": "1",
...
},
...
},
...
},
...
}
合并到
{
...
"blah":
{
"params":
{
"foo":
{
"default": "bar",
"value": "val",
"misc": "1",
...
},
...
},
...
},
...
}
使用PHP对象处理此问题的最佳方法是什么。
答案 0 :(得分:33)
将每个JSON字符串解码为关联数组,合并结果并重新编码
$a1 = json_decode( $json1, true );
$a2 = json_decode( $json2, true );
$res = array_merge_recursive( $a1, $a2 );
$resJson = json_encode( $res );
<强>更新强> 如果您有特定的合并要求,那么您需要编写自己的合并功能。 我在下面写了一个符合问题所述要求的文件。 如果您还有其他未提及的要求,可能需要进行调整。
<?php
$json1 = '
{
"blah":
{
"params":
{
"foo":
{
"default": "bar",
"misc": "0"
}
},
"lost":
{
"one": "hat",
"two": "cat"
}
}
}';
$json2 = '
{
"blah":
{
"lost": "gone",
"params":
{
"foo":
{
"value": "val",
"misc": "1"
}
}
},
"num_array": [12, 52, 38]
}';
$a1 = json_decode( $json1, true );
$a2 = json_decode( $json2, true );
/*
* Recursive function that merges two associative arrays
* - Unlike array_merge_recursive, a differing value for a key
* overwrites that key rather than creating an array with both values
* - A scalar value will overwrite an array value
*/
function my_merge( $arr1, $arr2 )
{
$keys = array_keys( $arr2 );
foreach( $keys as $key ) {
if( isset( $arr1[$key] )
&& is_array( $arr1[$key] )
&& is_array( $arr2[$key] )
) {
$arr1[$key] = my_merge( $arr1[$key], $arr2[$key] );
} else {
$arr1[$key] = $arr2[$key];
}
}
return $arr1;
}
$a3 = my_merge( $a1, $a2);
$json3 = json_encode( $a3 );
echo( $json3 );
/*
{
"blah":
{
"params":
{
"foo":
{
"default": "bar",
"misc": "1",
"value": "val"
}
},
"lost": "gone"
},
"num_array": [12,52,38]
}
*/
答案 1 :(得分:5)
使用array-replace-recursive()
http://www.php.net/manual/en/function.array-replace-recursive.php
它完全符合您的要求。
答案 2 :(得分:0)
对@meouw的代码(上面)进行了一些增强,可以合并对象中的索引数组。
$a = '{ "things": ["abc"], "apple":"pear" }';
$b = '{ "things": ["123"] }';
$a1 = json_decode( $a, true );
$b1 = json_decode( $b, true );
echo json_encode(deep_merge($a1,$b1));
// output: {"things":["abc","123"],"apple":"pear"}
function deep_merge( $arr1, $arr2 )
{
$keys = array_keys( $arr2 );
foreach( $keys as $key ) {
if (isset($arr1[$key]) && is_numeric($key) ) {
array_push($arr1,$arr2[$key]);
}
else if( isset($arr1[$key]) && is_array($arr1[$key]) && is_array($arr2[$key])) {
$arr1[$key] = deep_merge( (array)$arr1[$key],(array) $arr2[$key] );
} else {
$arr1[$key] = $arr2[$key];
}
}
return $arr1;
}
否则,输出将为{"things":["123"],"apple":"pear"}
答案 3 :(得分:0)
@infinum仅提供链接的答案表明,array_replace_recursive()
是完成此任务的正确的本机工具。
我不确定为什么OP接受@meouw的回答是array_merge_recursive()
是不适当的调用,而当php已经有一个本地调用时,滚动自己的自定义递归脚本是不必要的工作。
带有绿色的勾号和对部分错误的,带有次优的创可贴答案的大量投票,此页面很可能会误导研究人员,并且代表没有吸引力的候选人来关闭将来重复的问题。
脚本只需要将json字符串解码为数组,调用递归函数,然后对结果数组进行重新编码。
这里是如何准备json字符串和使用array_replace_recursive()
的完整演示。
代码:(Demo)
$json1 = '{"blah":{"params":{"foo":{"default":"bar","misc":"0"}}}}';
$json2 = '{"blah":{"params":{"foo":{"value":"val","misc":"1"}}}}';
echo json_encode(
array_replace_recursive(
json_decode($json1, true),
json_decode($json2, true)
),
JSON_PRETTY_PRINT
);
输出:
{
"blah": {
"params": {
"foo": {
"default": "bar",
"misc": "1",
"value": "val"
}
}
}
}