PHP 提供 array_merge() 和 + 運算符兩種數組合併方式,對數字鍵、字符串鍵、重複鍵的處理邏輯截然不同,選錯易導致數據丟失或結構錯亂。
| 場景 | array_merge() | $a + $b |
|---|---|---|
| 字符串鍵重複 | 後者覆蓋前者 | 前者保留,後者忽略 |
| 數字鍵重複 | 重新索引 (0,1,2...) | 前者保留,後者忽略 |
| 數字鍵不重複 | 重新索引 | 保留原鍵名 |
| 字符串鍵不重複 | 合並保留 | 合並保留 |
| 返回值類型 | 新數組 | 新數組 |
<?php
$a = ['d' => 'aass', 'e' => 'adsdfd', 'asd' => 'asdsdd', 'ddfg' => 'dssdf'];
$b = ['d' => 'adddd', 0 => 'adsdfd', 1 => 'asdfsddddd', 'd' => 'aass'];
// array_merge: 字符串鍵 'd' 後者覆蓋,數字鍵 0,1 重新索引追加
$merged = array_merge($a, $b);
/* 結果:
[
'd' => 'aass', // $b 最後的 'd' => 'aass' 覆蓋
'e' => 'adsdfd',
'asd' => 'asdsdd',
'ddfg' => 'dssdf',
0 => 'adsdfd', // 重新索引 0
1 => 'asdfsddddd', // 重新索引 1
]
*/
// + 運算符: 字符串鍵 'd' 保留 $a,數字鍵 0,1 保留 $b 原鍵
$union = $a + $b;
/* 結果:
[
'd' => 'aass', // $a 保留
'e' => 'adsdfd',
'asd' => 'asdsdd',
'ddfg' => 'dssdf',
0 => 'adsdfd', // $b 保留
1 => 'asdfsddddd', // $b 保留
]
*/
// 情況 1: 純數字索引數組
$arr1 = [1, 2, 3]; // [0=>1, 1=>2, 2=>3]
$arr2 = [4, 5]; // [0=>4, 1=>5]
array_merge($arr1, $arr2); // [0=>1, 1=>2, 2=>3, 3=>4, 4=>5] 重新索引
$arr1 + $arr2; // [0=>1, 1=>2, 2=>3] $arr2 完全被忽略!
// 情況 2: 關聯數組
$assoc1 = ['a' => 1, 'b' => 2];
$assoc2 = ['b' => 20, 'c' => 30];
array_merge($assoc1, $assoc2); // ['a'=>1, 'b'=>20, 'c'=>30] 後者覆蓋
$assoc1 + $assoc2; // ['a'=>1, 'b'=>2, 'c'=>30] 前者優先
// 情況 3: 混合鍵名
$mix1 = [0 => 'a', 'x' => 1];
$mix2 = [1 => 'b', 'x' => 2];
array_merge($mix1, $mix2); // [0=>'a', 1=>'b', 'x'=>2] 數字重新索引,字符串覆蓋
$mix1 + $mix2; // [0=>'a', 'x'=>1, 1=>'b'] 保留所有原鍵
array_merge() (最常用)$a + $barray_merge($defaults, $user)$a + $b + $carray_merge_recursive() 或自定義遞歸函數+ 運算符略快 (語言構造,無函數調用開銷)array_merge() 支持可變參數:array_merge($a, $b, $c...)// ❌ 錯誤:以為 + 能合併數字索引
$list = [1,2,3] + [4,5]; // 結果 [1,2,3] 而非 [1,2,3,4,5]
// ✅ 正確:數字索引合併用 array_merge
$list = array_merge([1,2,3], [4,5]); // [1,2,3,4,5]
// ❌ 陷阱:字符串鍵名數字化
$arr = ['0' => 'a', '1' => 'b']; // 這是字符串鍵!
$arr + ['0' => 'c']; // ['0'=>'a', '1'=>'b'] 字符串鍵 '0' 不覆蓋
記憶口訣:
array_merge重索引、後蓋前;+保鍵名、前擋後。