1

In PHP, array_replace_recursive() does two things according to the documentation:

  • If a key from the first array exists in the second array, its value will be replaced by the value from the second array.
  • If the key exists in the second array, and not the first, it will be created in the first array.

Is there an alternative that only does the replacement, and doesn't create new keys?

For example:

$array = [
  'apple' => TRUE,
  'pear' => TRUE,
  'basket' => [
    'banana' => TRUE,
  ],
  'punnet' => [
    'strawberry' => TRUE,
  ],
];

$replacement = [
  'banana' => [
    'REPLACEMENT!'
  ],
];

The result should be:

$array = [
  'apple' => TRUE,
  'pear' => TRUE,
  'basket' => [
    'banana' => [
      'REPLACEMENT!'
    ],
  ],
  'punnet' => [
    'strawberry' => TRUE,
  ],
];
4
  • Could you show a specific example of what you want to achieve. Commented Mar 9, 2021 at 17:38
  • You have misunderstood array_replace_recursive(). Commented Mar 10, 2021 at 12:56
  • array_replace_recursive() doesn't do what I need. That's not the same as not understanding it. Also, I'd argue that what array_replace_recursive() does is not 'replace'. Commented Mar 10, 2021 at 15:49
  • @joachim Nope, it does what it says. Keys need to match between the first array and second array for replacement. See this link to understand the difference between your replacement and the one in the link. sandbox.onlinephpfunctions.com/code/… Commented Mar 10, 2021 at 17:58

2 Answers 2

0

You will need to use array_intersect_key() to create an array that contains only the keys that are in the two arrays, then you can merge.

$array1 = [
    'a' => 1,
    'b' => 2,
    'c' => 3,
    'd' => 4,
];

$array2 = [
    'b' => 14,
    'c' => 70,
    'f' => 5,
];

// $array2 has to be the first arguments for $inter to have its value instead of the value of $array1
$inter = array_intersect_key($array2, $array1);

$merged = array_replace_recursive($array1, $inter);

// Merged will be: 
[
    'a' => 1,
    'b' => 14,
    'c' => 70,
    'd' => 4,
];

EDIT For this to work recursively, you can use this function found here

/** 
* Recursively computes the intersection of arrays using keys for comparison.
* 
* @param   array $array1 The array with master keys to check.
* @param   array $array2 An array to compare keys against.
* @return  array associative array containing all the entries of array1 which have keys that are present in array2.
**/
function array_intersect_key_recursive(array $array1, array $array2) {
    $array1 = array_intersect_key($array1, $array2);

    foreach ($array1 as $key => &$value) {
        if (is_array($value) && is_array($array2[$key])) {
            $value = array_intersect_key_recursive($value, $array2[$key]);
        }
    }

    return $array1;
}
Sign up to request clarification or add additional context in comments.

4 Comments

It needs to be recursive, not just the first layer.
Ok. PHP does not have that directly. We need to implemented it. Hopefully it has already been done. I've edited the answer.
I'm not sure intersection is the right thing to do here. I've added an example to the question.
The haystack has banana is inside basket; the needle has banana on the first level -- neither of these snippets will work as required.
0

This does what I needed:

array_walk_recursive($array, function(&$value, $key, $replacements) {
  if (isset($replacements[$key])) {
    $value = $replacements[$key];
  }
}, ['replace' => 'replacement']);

1 Comment

This unexplained answer works with the sample data because the sought value/replacement is on a leaf-node.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.