Skip to content

Instantly share code, notes, and snippets.

@adrian-enspired
Last active October 13, 2021 21:48
Show Gist options
  • Save adrian-enspired/e766b37334130ea04eaf to your computer and use it in GitHub Desktop.
Save adrian-enspired/e766b37334130ea04eaf to your computer and use it in GitHub Desktop.
array_merge|replace_recursive are frustrating.

say you have two arrays, $a1 and $a2, and you want to combine them.

<?php

$a1 = [
  'a' => 'foo',
  'b' => ['bar']
];
$a2 = [
  'a' => 'bar',
  'b' => ['foo']
];

array_merge_recursive() merges all values (all values — even if they're not in arrays. it creates arrays!).

<?php 
var_dump(array_merge_recursive($a1, $a2));
/*
array(2) {
  ["a"]=>
  array(2) {
    [0]=>
    string(3) "foo"
    [1]=>
    string(3) "bar"
  }
  ["b"]=>
  array(2) {
    [0]=>
    string(3) "bar"
    [1]=>
    string(3) "foo"
  }
} */

array_replace_recursive() replaces all values.

<?php
var_dump(array_replace_recursive($a1, $a2));
/*
array(2) {
  ["a"]=>
  string(3) "bar"
  ["b"]=>
  array(1) {
    [0]=>
    string(3) "foo"
  }
} */

typically, what i actually want is to merge arrays, and replace non-array values. but there's no built-in function that does this.

<?php
var_dump(array_extend_recursive($a1, $a2));
/*
array(2) {
  ["a"]=>
  string(3) "bar"
  ["b"]=>
  array(2) {
    [0]=>
    string(3) "bar"
    [1]=>
    string(3) "foo"
  }
} */

here you go.

<?php
function array_extend_recursive(array $subject, array ...$extenders) {
  foreach ($extenders as $extend) {
    foreach ($extend as $k => $v) {
      if (is_int($k)) {
        $subject[] = $v;
      } elseif (isset($subject[$k]) && is_array($subject[$k]) && is_array($v)) {
        $subject[$k] = array_extend_recursive($subject[$k], $v);
      } else {
        $subject[$k] = $v;
      }
    }
  }
  return $subject;
}
@adrian-enspired
Copy link
Author

anyone is free to use this without restriction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment