陣列操作是 PHP 日常開發的高頻場景。array_merge()、array_merge_recursive()、array_combine() 三個函數雖名稱相似,但行為差異巨大。搞不清規則極易導致資料覆蓋、索引錯位等隱蔽 Bug。本文通過圖解與實測,徹底釐清三者異同。
<?php $face = ['J', 'Q', 'K', 'A']; // 索引 0-3 $numbered = ['2','3','4','5','6','7','8','9']; // 索引 0-7 $cards = array_merge($face, $numbered); // 結果:['J','Q','K','A','2','3','4','5','6','7','8','9'] 索引 0-11 連續 ?>
<?php $a = ['color' => 'red', 'size' => 'M']; $b = ['color' => 'blue', 'shape' => 'circle']; $merged = array_merge($a, $b); // 結果:['color' => 'blue', 'size' => 'M', 'shape' => 'circle'] ?>
<?php $a = [5 => 'a', 8 => 'b']; $b = [10 => 'c']; $merged = array_merge($a, $b); // 結果:[0 => 'a', 1 => 'b', 2 => 'c'] 索引完全重置! ?>
遇到相同字串鍵時,不覆蓋,而是將兩值合併為新陣列(遞歸處理)。數字鍵行為同 array_merge()。
<?php
$class1 = ['John' => 100, 'James' => 85];
$class2 = ['Micky' => 78, 'John' => 45];
$scores = array_merge_recursive($class1, $class2);
/* 結果:
[
'John' => [100, 45], // 合併為陣列!
'James' => 85,
'Micky' => 78
]
*/
?>
<?php
$a = ['user' => ['name' => 'Tom', 'tags' => ['php']]];
$b = ['user' => ['email' => 'tom@ex.com', 'tags' => ['laravel']]];
$merged = array_merge_recursive($a, $b);
/* 結果:
'user' => [
'name' => 'Tom',
'email' => 'tom@ex.com',
'tags' => ['php', 'laravel'] // 遞歸合併!
]
*/
?>
ValueError(PHP 8.0+)<?php $abbreviations = ['AL', 'AK', 'AZ', 'AR']; $states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas']; $map = array_combine($abbreviations, $states); // 結果:['AL'=>'Alabama', 'AK'=>'Alaska', 'AZ'=>'Arizona', 'AR'=>'Arkansas'] ?>
id => row 映射表| 特性 | array_merge | array_merge_recursive | array_combine |
|---|---|---|---|
| 主要用途 | 合併多個陣列 | 合併並保留衝突值 | 建立鍵值映射 |
| 字串鍵衝突 | 後覆蓋前 | 合併為陣列 | 不適用(第一陣列為鍵) |
| 數字鍵處理 | 重置索引 | 重置索引 | 不適用 |
| 參數數量 | 1+ | 1+ | 固定 2 個 |
| 長度要求 | 無 | 無 | 必須相等 |
| 回傳型別 | 陣列 | 陣列(值可能為陣列) | 關聯陣列 |
| 場景 | 推薦函數 | 理由 |
|---|---|---|
| 多個設定陣列合併,後者優先 | array_merge | 符合配置覆蓋語義 |
| 收集多來源同名欄位(如多表單提交) | array_merge_recursive | 保留所有值不丟失 |
| ID 列表與對應資料組合成查找表 | array_combine | O(1) 查找效能 |
| 保留原有數字索引不重置 | + 運算子 | $a + $b 保留鍵不重置 |
<?php $a = [1 => 'a', 2 => 'b']; $b = [2 => 'c', 3 => 'd']; $c = $a + $b; // 結果:[1 => 'a', 2 => 'b', 3 => 'd'] // $a 的鍵優先,$b 只有不存在的鍵才會加入 ?>
注意:+ 運算子不重置數字索引,不覆蓋既有鍵,語義更接近「補全」。
記住核心規則,陣列合併不再踩坑,代碼更健壯優雅。