Parapluie
Parapluie

Reputation: 736

php array_merge_recursive is replacing some key strings with numeric keys

I am experiencing unexpected behaviour with the php function array_merge_recursive. Any advice or work-around would be appreciated.

The problem is with unexpected replacement of string keys with numeric key during the array_merge_recursive.

Details:

I have three associative arrays ($birthdays,$custom,$natHolidays), to which these values are programmatically added:

$birthdays['0808'][] = 'John MacLoud';
$birthdays['0819'][] = 'Susan MacLoud';
$birthdays['0903'][] = 'Catherine MacLoud';
$birthdays['1008'][] = 'Daisy Simpson';
$birthdays['1015'][] = 'Phillip MacLoud';
$birthdays['1212'][] = 'Aloysius Simpson';
$natHolidays['0317'][] = 'St. Patrick's Day';
$natHolidays['0317'][] = 'la Saint-Patrick';
$natHolidays['0701'][] = 'Canada Day';
$natHolidays['0701'][] = 'la fête du Canada';
$natHolidays['1031'][] = 'Hallowe'en';
$natHolidays['1031'][] = 'l'Halloween';
$natHolidays['1031'][] = 'Hallowe'en';
$natHolidays['1031'][] = 'l'Halloween';
$natHolidays['1111'][] = 'Remembrance Day';
$natHolidays['1111'][] = 'jour du souvenir';
$natHolidays['1224'][] = 'Christmas Eve';
$natHolidays['1224'][] = 'la vielle de Noël';
$natHolidays['1225'][] = 'Christmas';
$natHolidays['1225'][] = 'Noël';
$natHolidays['1226'][] = 'Boxing Day';
$natHolidays['1226'][] = 'le lendemain de Noël';
$natHolidays['1231'][] = 'New Year's Eve';
$natHolidays['1231'][] = 'vielle du jour de 'an';
$natHolidays['0907'][] = 'Labour Day';
$natHolidays['0907'][] = 'la fête du Travail';
$natHolidays['0922'][] = 'Equinox';
$natHolidays['0922'][] = 'l'equinoxe';
$natHolidays['1012'][] = 'Thanksgiving';
$natHolidays['1012'][] = 'l'action de grace';
$natHolidays['1101'][] = 'Daylight Savings ends';
$natHolidays['1101'][] = 'fall back';
$natHolidays['1221'][] = 'Solstice';
$natHolidays['1221'][] = 'le solstice';
$custom['0922'][] = 'Test value 1';
$custom['1122'][] = 'Test value 2';

I then merge the arrays: $dates = array_merge_recursive($birthdays,$custom,$natHolidays);

The resulting $dates array outputs:

["0808"]=>
  array(1) {
    [0]=>
    string(13) "John MacLoud"
  }
  ["0819"]=>
  array(1) {
    [0]=>
    string(13) "Susan MacLoud"
  }
  ["0903"]=>
  array(1) {
    [0]=>
    string(14) "Catherine MacLoud"
  }
  [0]=>
  array(1) {
    [0]=>
    string(15) "Daisy Simpson"
  }
  [1]=>
  array(1) {
    [0]=>
    string(14) "Phillip MacLoud"
  }
  [2]=>
  array(1) {
    [0]=>
    string(13) "Aloysius Simpson"
  }
  ["0317"]=>
  array(2) {
    [0]=>
    string(22) "St. Patrick's Day"
    [1]=>
    string(16) "la Saint-Patrick"
  }
  ["0701"]=>
  array(2) {
    [0]=>
    string(10) "Canada Day"
    [1]=>
    string(18) "la fête du Canada"
  }
  [3]=>
  array(2) {
    [0]=>
    string(15) "Hallowe'en"
    [1]=>
    string(16) "l'Halloween"
  }
  [4]=>
  array(2) {
    [0]=>
    string(15) "Remembrance Day"
    [1]=>
    string(16) "jour du souvenir"
  }
  [5]=>
  array(2) {
    [0]=>
    string(13) "Christmas Eve"
    [1]=>
    string(18) "la vielle de Noël"
  }
  [6]=>
  array(2) {
    [0]=>
    string(9) "Christmas"
    [1]=>
    string(5) "Noël"
  }
  [7]=>
  array(2) {
    [0]=>
    string(10) "Boxing Day"
    [1]=>
    string(21) "le lendemain de Noël"
  }
  [8]=>
  array(2) {
    [0]=>
    string(19) "New Year's Eve"
    [1]=>
    string(26) "vielle du jour de 'an"
  }
  ["0907"]=>
  array(2) {
    [0]=>
    string(10) "Labour Day"
    [1]=>
    string(19) "la fête du Travail"
  }
  ["0922"]=>
  array(3) {
    [0]=>
    string(14) "Test value 1"
    [1]=>
    string(7) "Equinox"
    [2]=>
    string(15) "l'equinoxe"
  }
  [9]=>
  array(1) {
    [0]=>
    string(15) "Test value 2"
  }
  [10]=>
  array(2) {
    [0]=>
    string(12) "Thanksgiving"
    [1]=>
    string(22) "l'action de grace"
  }
  [11]=>
  array(2) {
    [0]=>
    string(21) "Daylight Savings ends"
    [1]=>
    string(9) "fall back"
  }
  [12]=>
  array(2) {
    [0]=>
    string(8) "Solstice"
    [1]=>
    string(11) "le solstice"
  }

The only pattern I have noticed is that any key string starting with a '0' (i.e. 0130) works as expected, and any key string starting with a '1' (i.e. 1022) replaces the string key with a sequential numeric key.

Thoughts?

Btw:

Creating the new tag 'array-merge-recursive' requires at least 1500 reputation. Try something from the existing tags list instead.

Upvotes: 1

Views: 380

Answers (1)

Andrea Golin
Andrea Golin

Reputation: 3559

PHP is loosely typed, and it is casting your array keys.

You could use integer as keys to avoid the cast:

$arr[10] = 'foo';

and not

$arr["10"] = 'foo';

Updated answer:

The casting is treating keys starting with "0" as strings, and so far so good. The other keys are treated like integers, and array_merge will renumber them starting from 0 (as it is happening here).

I know you are using array_merge_recursive, but it appears to behave the same.

Upvotes: 1

Related Questions