phpjsonarray-merge

Merge two json overwriting different innested objects in php


I have two json objects with innested objects and I need to merge them into one object overwriting the original values with the ones from the second object.

First JSON

{
   "field 1" : {
      "key 1": "value 1",
      "key 2": {
         "subkey 1": "subvalue 1",
         "subkey 2": "subvalue 2"
      },
      "key 3": "value 3"
   },
   "field 2": {
      "key 4": "value 4",
      "key 5": "value 5"
   },
   "field 3": {
      "key6": "value 6"
   }
}

Second JSON, contains only the fields that have values that differs from the first JSON

{
   "field 1" : {
      "key 1": "value 10",
      "key 2": {
         "subkey 2": "subvalue 20"
      }
   },
   "field 2": {
      "key 4": "value 40"
   }
}

Expected result, the first JSON with the values modified of the second JSON

{
   "field 1" : {
      "key 1": "value 10",
      "key 2": {
         "subkey 1": "subvalue 1",
         "subkey 2": "subvalue 20"
      },
      "key 3": "value 3"
   },
   "field 2": {
      "key 4": "value 40",
      "key 5": "value 5"
   },
   "field 3": {
      "key6": "value 6"
   }
}

I already tried with array_merge but when it finds the same key in both objects replace the value of the first with the value of the second. In this case the result is field 1 and field 2 from the second JSON and field 3 from the first.

Array_merge_recursive instead adds the second values to the first ones so that, for example, for "key 1" the values becomes

"[value 1, value 10]"

Any help?

Ps. In this example I used JSON objects with only two levels but there could be more


Solution

  • I think that you want array replace instead of merge.

    <?php
    $j1 = '{
       "field 1" : {
          "key 1": "value 1",
          "key 2": {
             "subkey 1": "subvalue 1",
             "subkey 2": "subvalue 2"
          },
          "key 3": "value 3"
       },
       "field 2": {
          "key 4": "value 4",
          "key 5": "value 5"
       },
       "field 3": {
          "key6": "value 6"
       }
    }';
    
    $j2 = '{
        "field 1" : {
           "key 1": "value 10",
           "key 2": {
              "subkey 2": "subvalue 20"
           }
        },
        "field 2": {
           "key 4": "value 40"
        }
     }';
    
    $a1 = json_decode($j1, true);
    
    $a2 = json_decode($j2, true);
    
    
    $a = array_replace_recursive($a1, $a2);
    print_r( json_encode($a, JSON_PRETTY_PRINT));
    ?>
    

    The output

    {
        "field 1": {
            "key 1": "value 10",
            "key 2": {
                "subkey 1": "subvalue 1",
                "subkey 2": "subvalue 20"
            },
            "key 3": "value 3"
        },
        "field 2": {
            "key 4": "value 40",
            "key 5": "value 5"
        },
        "field 3": {
            "key6": "value 6"
        }
    }
    

    Check https://www.php.net/manual/en/function.array-replace-recursive