array_merge() 可合併多個陣列,遇到相同的陣列索引,將由後方陣列的值取代前一個值。
如:
$d = array(
'a' => 111,
'b' => 222,
);
$e = array(
'a' => 123,
'c' => 333,
);
var_dump(array_merge($d, $e));
執行結果為:
array(3) {
["a"]=>
int(123)
["b"]=>
int(222)
["c"]=>
int(333)
}
此特性常被用來做設定選項合併,如:
function__construct(array $config){
$defaultsStyle = array(
'display' => true,
'color' => 'red',
'size' => '14px',
);
$settings = array_merge($defaultStyle, $config);
// initialize by $settings
}
上面的寫法可以讓預設的三項索引「display」、「color」、「size」一定存在,不需特別在做 array_key_exists() 檢查,且外部傳入的數值,會將內定的預設值覆蓋掉。
不過只有字串型態的陣列索引,經過 array_merge() 以後可以保留原有的索引名稱,若為數字型態的陣列索引,array_merge() 會將原有索引打掉重新排列。
如:
$d = array(
0 => 111,
1 => 222,
);
$e = array(
9 => 123,
7 => 333,
);
var_dump(array_merge($d, $e));
執行的結果會是:
array(4) {
[0]=>
int(111)
[1]=>
int(222)
[2]=>
int(123)
[3]=>
int(333)
}
另外 array_merge() 有個很奇怪的行為,假設陣列的索引是「類似數字」的字串 (不曉得判斷規則為何),像是 “100”、”200″,經過 array_merge() 時會被當成數字型索引處理。
如:
$d = array(
'100' => 111,
'200' => 222,
);
$e = array(
'100' => 100,
'300' => 333,
);
var_dump(array_merge($d, $e));
執行後為:
array(4) {
[0] =>
int(111)
[1] =>
int(222)
[2] =>
int(100)
[3] =>
int(333)
}
若索引名稱為 “001”、”002″,經過 array_merge() 才會被當成字串,不會有上述情況發生。
要避免索引被吃掉,可以改用 array unioin operator:
$d = array(
'100' => 111,
'200' => 222,
);
$e = array(
'100' => 100,
'300' => 333,
);
var_dump($d + $e));
陣列索引會被保留下來:
array(3) {
[100] =>
int(111)
[200] =>
int(222)
[300] =>
int(333)
}
不過要注意的是,array union operator 遇到相同索引時,陣列值並不會被後方的陣列取代 ($merged[‘100’] 會是 111 而非 100),所以使用時要注意順序問題。
總之,’100’、’200′ 被 array_merge() 當成數字讓我極度不爽。
備註:
array_merge() 中可能是用 is_numeric() 去判斷 key 是否為數字
而 is_numeric( strval("123") ) === true
看來有人問過這問題,而且發問的人快要起笑了 XD
https://bugs.php.net/bug.php?id=25470