PHP 提供兩種陣列合併方式:+ 運算子與 array_merge()。它們對「數字鍵」與「字串鍵」的處理邏輯截然不同,誤用極易導致資料遺失或索引錯亂。本文通過實例徹底釐清兩者行為差異。
<?php
$r = [1,2,3,4,5,6]; // 索引 0-5
$e = [7,8,9,10]; // 索引 0-3
var_dump($r + $e);
// 輸出:[0=>1, 1=>2, 2=>3, 3=>4, 4=>5, 5=>6]
// + 號:後陣列同索引鍵被忽略,長度以第一個陣列為準
var_dump(array_merge($r, $e));
// 輸出:[0=>1, 1=>2, 2=>3, 3=>4, 4=>5, 5=>6, 6=>7, 7=>8, 8=>9, 9=>10]
// array_merge:重新索引,後陣列值追加到前陣列末尾
<?php
$r = ['r' => 1, 2, 3, 4, 5, 6]; // 'r' => 1, 0=>2, 1=>3...
$e = ['r' => 7, 8, 9, 10]; // 'r' => 7, 0=>8, 1=>9...
var_dump($r + $e);
// ['r' => 1, 0=>2, 1=>3, 2=>4, 3=>5, 4=>6]
// 字串鍵 'r' 以第一個陣列為準,數字鍵 0-3 同理被忽略
var_dump(array_merge($r, $e));
// [0=>1, 1=>2, 2=>3, 3=>4, 4=>5, 5=>6, 6=>7, 7=>8, 8=>9]
// 字串鍵 'r' 後值覆蓋前值,但因重新索引,'r' 變為數字鍵 0,原數字鍵順延
| 場景 | 推薦 | 理由 |
|---|---|---|
| 多個關聯陣列合併配置,後者覆蓋前者 | array_merge() | 字串鍵自然覆蓋,符合配置疊加直覺 |
| 多個列表陣列拼接,保留所有值 | array_merge() | 重新索引生成連續列表 |
| 預設值陣列 + 用戶輸入陣列,用戶值優先 | $user + $defaults | + 號保留第一次出現的值(用戶值在前) |
| 多維陣列遞歸合併 | array_merge_recursive() 或自定義遞歸 | 上述兩者均為淺層合併 |
<?php
$a = ['0' => 'a', '1' => 'b']; // 字串鍵 '0','1'
$b = ['0' => 'c', '2' => 'd'];
var_dump($a + $b); // ['0'=>'a', '1'=>'b', '2'=>'d'] 字串鍵視同關聯鍵
var_dump(array_merge($a, $b)); // [0=>'a', 1=>'b', 2=>'c', 3=>'d'] 強制轉數字索引重排
array_merge,列表拼接用 array_merge,預設值覆蓋用 +。array_values() 或使用 ... 運算子 (PHP 7.4+):[...$a, ...$b]。'0' vs 0),來源資料統一 array_keys() 檢查。搞清這兩者的語義邊界,能避免 90% 的陣列合併 Bug,也是 Code Review 時的高頻檢查點。