Skip to content
Advertisement

Failing to array_merge(), same output prior to loop

I’ve seen numerous related questions, none answered this for me – I apologize if that’s due to my lack of knowledge…

I have an array, $contacts, where each record looks like the below, with 1-many contacts:

[{internal_id}]=>
  array(3) {
    [0]=>
    array(6) {
      ["name"]=>
      string(13) "matching name"
      ["bphone"]=>
      string(13) "(123)345-5678"
      ["cphone"]=>
      string(13) "(321)345-6857"
      ["hphone"]=>
      string(13) "(123)543-5790"
      ["email"]=>
      string(0) ""
      ["email2"]=>
      string(0) ""
    }
    [1]=>
    array(6) {
      ["name"]=>
      string(13) "matching name"
      ["bphone"]=>
      string(13) "(123)345-5678"
      ["cphone"]=>
      string(0) ""
      ["hphone"]=>
      string(0) ""
      ["email"]=>
      string(20) "margethis@please.com"
      ["email2"]=>
      string(21) "mergethis2@please.com"
    }
    [2]=>
    array(6) {
      ["name"]=>
      string(17) "not matching name"
      ["bphone"]=>
      string(13) "(123)987-6453"
      ["cphone"]=>
      string(13) "(321)789-3546"
      ["hphone"]=>
      string(0) ""
      ["email"]=>
      string(21) "email@popularmail.com"
      ["email2"]=>
      string(22) "email2@popularmail.com"
    }
  }

I want to combine any like names, per record, keeping the relevant contact info. Trying this:

    $i = 1; //1 > 0 so no need to +1 each time it's used in this case
    foreach($contacts as $contact){
        if($contact['name'] == $contacts[$i]['name']){
            $contact = array_merge($contact, $contacts[$i]);
            unset($contacts[$i]);
        }
        $i++;
    }

My expected/desired output would be:

[{internal_id}]=>
  array(2) {
    [0]=>
    array(6) {
      ["name"]=>
      string(13) "matching name"
      ["bphone"]=>
      string(13) "(123)345-5678"
      ["cphone"]=>
      string(13) "(321)345-6857"
      ["hphone"]=>
      string(13) "(123)543-5790"
      ["email"]=>
      string(20) "margethis@please.com"
      ["email2"]=>
      string(21) "mergethis2@please.com"
    }
    [1]=>
    array(6) {
      ["name"]=>
      string(17) "not matching name"
      ["bphone"]=>
      string(13) "(123)987-6453"
      ["cphone"]=>
      string(13) "(321)789-3546"
      ["hphone"]=>
      string(0) ""
      ["email"]=>
      string(21) "email@popularmail.com"
      ["email2"]=>
      string(22) "email2@popularmail.com"
    }
  }

But the loop isn’t having any effect, at least not that I can find. My actual output matches the initial array.

What am I missing here?

EDIT/UPDATE: Simple mix up on passing by reference/value. Thanks @Barmar for the quick solution. No changes were reflected in the array because I never actually told php to update those values. Shocking how that works.

Advertisement

Answer

There’s two reasons why your code doesn’t work:

  1. Assigning to $contact doesn’t change the array, it just reassigns the variable.
  2. array_merge() doesn’t modify the array in place, it returns a new array.

You can solve both problems by making $contact a reference variable.

foreach ($contacts as &$contact) {
    ...
}
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement