시작 오늘 분석할 코드
array_merge()는 두 개 이상의 배열을 하나로 합쳐 새 배열을 반환하는 함수입니다. 단순해 보이지만 키가 겹칠 때 어떤 값이 살아남는지, 숫자 키가 어떻게 재정렬되는지를 이해해야 예상치 못한 데이터 손실을 막을 수 있습니다.
<?php $data = array("TV1" => "500", "TV2" => "1000", "RADIO1" => "800"); $add_data = array("TV1" => "2000", "RADIO2" => "600"); $result = array_merge($data, $add_data); // TV1 키가 겹침 → $add_data의 "2000"으로 덮어씀 // RADIO1·RADIO2는 겹치지 않으므로 둘 다 포함 print "<PRE>"; print_r($result); print "</PRE>"; ?>
실제 출력 미리보기
Array
(
[TV1] => 2000 ← $add_data가 덮어씀 (500 → 2000)
[TV2] => 1000
[RADIO1] => 800
[RADIO2] => 600 ← $add_data에서 새로 추가
)
용어 용어 정리
array_merge()두 개 이상 배열을 순서대로 합쳐 새 배열 반환. 원본 배열은 변경되지 않음
문자열 키배열의 키가 문자열인 경우 (연관 배열). 충돌 시 나중 배열 값으로 덮어씀
숫자 키배열의 키가 정수인 경우 (인덱스 배열). 병합 시 0부터 재인덱싱됨
재인덱싱숫자 키를 병합 순서에 맞춰 0, 1, 2… 로 새로 부여하는 것
+ 연산자배열 합집합 연산자. 앞쪽 배열의 키를 우선 보존 — array_merge와 반대
array_merge_recursive()문자열 키 충돌 시 덮어쓰지 않고 두 값을 서브 배열로 합침
스프레드 연산자PHP 7.4+에서 [...$a, ...$b] 문법으로 array_merge 대체 가능
원본 불변array_merge()는 새 배열을 반환하며 인자로 전달된 배열은 변경하지 않음
1 기본 동작 원리 — 왜 두 배열을 순서대로 합치는가?
첫 번째 배열이 기초, 두 번째 배열이 추가·덮어쓰기
array_merge($a, $b)는 $a 전체를 먼저 복사한 뒤 $b를 뒤에 이어 붙이는 방식으로 동작합니다. 이때 두 가지 규칙이 적용됩니다: ① 문자열 키가 겹치면 $b의 값이 $a의 값을 덮어씁니다. ② 숫자 키는 겹치더라도 덮어쓰지 않고 0부터 재인덱싱하여 모두 포함합니다.
1
$data 복사TV1=500, TV2=1000, RADIO1=800 을 결과 배열에 넣음
2
$add_data 순회 — TV1 충돌 감지TV1=2000 → 이미 TV1 키가 있음 → 기존 500을 2000으로 교체
3
새 키 추가RADIO2=600 → 없던 키이므로 그냥 추가
4
새 배열 반환[TV1=2000, TV2=1000, RADIO1=800, RADIO2=600] 반환, 원본은 그대로
※ array_merge()는 새 배열을 반환합니다. $data나 $add_data 자체는 전혀 바뀌지 않습니다. 반드시 변수에 받아야 합니다.
2 문자열 키 충돌 — 왜 나중 배열이 이기는가?
덮어쓰기 방향은 항상 "뒤쪽 배열 우선"
같은 문자열 키가 두 배열 모두에 존재할 때 array_merge()는 두 번째(나중) 배열의 값으로 교체합니다. 이 설계는 "기본값 배열에 사용자 설정을 덮어씌운다"는 패턴을 자연스럽게 지원하기 위해서입니다. 기본값을 먼저, 사용자 값을 나중에 넣으면 사용자 설정이 이깁니다.
$defaults = ["color" => "red", "size" => "M", "stock" => true]; $user = ["color" => "blue"]; // 사용자가 색상만 변경 $final = array_merge($defaults, $user); // ["color"=>"blue", "size"=>"M", "stock"=>true] // color만 덮어쓰이고 나머지는 기본값 유지
이 패턴은 설정(config) 병합, 옵션 처리 함수에서 매우 자주 쓰입니다. 기본값 배열을 첫 번째 인수, 사용자 값 배열을 두 번째 인수로 넘기면 사용자가 지정한 항목만 교체되고 나머지는 기본값이 유지됩니다.
⚠️ 인수 순서를 반대로 넣으면 사용자 설정이 아니라 기본값이 최종 값이 됩니다. 항상 merge(기본값, 사용자설정) 순서를 지키세요.
3 숫자 키 재인덱싱 — 왜 0부터 다시 시작하는가?
숫자 키는 의미 없는 순서 번호 → 병합 후 재번호 매겨짐
숫자 키를 가진 배열(인덱스 배열)을 병합하면 키 값 자체는 무시되고, 모든 요소가 0부터 새로 번호 매겨집니다. 숫자 키는 의미 있는 식별자가 아니라 단순한 순서 번호이기 때문에, PHP는 이를 재조정해 연속된 인덱스를 유지합니다.
$a = ["사과", "귤"]; // [0=>"사과", 1=>"귤"] $b = ["바나나", "포도"]; // [0=>"바나나", 1=>"포도"] $result = array_merge($a, $b); // [0=>"사과", 1=>"귤", 2=>"바나나", 3=>"포도"] // 키 0이 겹쳤지만 덮어쓰지 않고 순서대로 재인덱싱
| 방법 |
숫자 키 충돌 시 |
문자열 키 충돌 시 |
array_merge($a, $b) |
재인덱싱 (모두 포함) |
$b 값으로 덮어씀 |
$a + $b |
$a 키 보존 ($b 값 무시) |
$a 키 보존 ($b 값 무시) |
※ 숫자 키를 보존하고 싶다면 + 연산자를 사용하세요. $a + $b는 $a에 없는 키만 $b에서 추가합니다.
4 + 연산자와의 차이 — 언제 어느 것을 써야 하는가?
+ 는 "앞쪽 배열 우선" — array_merge의 정반대
$a + $b 연산자는 $a에 없는 키만 $b에서 가져옵니다. $a에 이미 있는 키라면 $b의 값이 무시됩니다. array_merge()가 "나중 배열 우선"이라면, +는 "앞쪽 배열 우선"입니다.
array_merge($a, $b) — 나중 배열 우선
$a = ["x" => 1];
$b = ["x" => 99];
결과: ["x" => 99]
→ $b가 이긴다
$a + $b — 앞쪽 배열 우선
$a = ["x" => 1];
$b = ["x" => 99];
결과: ["x" => 1]
→ $a가 이긴다
언제 어느 것을?
- array_merge: 기본값에 사용자 설정을 덮어씌울 때 — merge(기본값, 사용자설정)
- +: 이미 설정된 값은 절대 바꾸지 말아야 할 때 — 사용자 설정이 기본값보다 우선
- +는 인덱스 배열에 주의: $a + $b 에서 $a[0]이 있으면 $b[0]은 무시됨
5 array_merge_recursive() — 덮어쓰지 않고 합치기
충돌 시 서브 배열로 묶어 두 값 모두 보존
같은 키가 충돌할 때 array_merge()는 덮어쓰지만, array_merge_recursive()는 두 값을 모두 살려서 서브 배열로 만듭니다. 여러 소스에서 같은 키로 데이터가 들어올 때 유용합니다.
$a = ["TV1" => "500"]; $b = ["TV1" => "2000"]; // 일반 merge — 덮어씀 print_r(array_merge($a, $b)); // Array ( [TV1] => 2000 ) ← 500 사라짐 // recursive merge — 서브 배열로 합침 print_r(array_merge_recursive($a, $b)); // Array ( [TV1] => Array ( [0] => 500 [1] => 2000 ) ) ← 둘 다 살아있음
⚠️ 모르고 array_merge_recursive()를 써서 예상치 못하게 서브 배열이 생기는 경우가 많습니다. 단순 덮어쓰기가 필요하다면 반드시 array_merge()를 사용하세요.
6 여러 배열 한 번에 병합 — 스프레드 연산자 활용
3개 이상 배열도 한 줄로 처리
array_merge()는 인수를 여러 개 받을 수 있습니다. 세 개 이상의 배열도 한 번에 병합 가능합니다. PHP 7.4부터는 스프레드 연산자(...)로 더 간결하게 표현할 수 있습니다.
// 3개 배열 한 번에 병합 $all = array_merge($a, $b, $c); // PHP 7.4+ 스프레드 연산자 — 동일한 결과 $all = [...$a, ...$b, ...$c]; // 배열의 배열을 한 번에 풀어서 합칠 때 $arrays = [$a, $b, $c]; $merged = array_merge(...$arrays); // 스프레드로 unpack
※ PHP 8.1부터는 [...$a, ...$b]가 문자열 키를 보존하면서 작동합니다. 숫자 키 재인덱싱도 동일하게 적용됩니다.
7 자주 하는 실수
| 실수 |
증상 |
해결 |
| 인수 순서를 거꾸로 넣음 |
사용자 설정이 아니라 기본값이 최종 값으로 남음 |
merge(기본값, 사용자설정) 순서 확인 |
| 숫자 키 배열에 + 연산자 사용 |
뒤쪽 배열 요소 대부분 무시됨 |
인덱스 배열은 array_merge() 사용 |
| 반환값을 변수에 안 받음 |
원본 배열이 바뀐 줄 알고 쓰다가 의도치 않은 값 참조 |
$result = array_merge() 형태로 항상 반환값 저장 |
| array_merge_recursive() 혼용 |
충돌 키가 갑자기 서브 배열로 바뀌어 오류 발생 |
목적에 맞는 함수 선택, 결과 자료형 확인 |
| NULL을 인수로 전달 |
PHP 8.0 미만에서 경고, 이후엔 TypeError |
array_merge() 전에 (array) 캐스팅 또는 null 체크 |
핵심 한 줄 요약
문자열 키 충돌나중(오른쪽) 배열이 이긴다 — 앞쪽 값이 덮어씌워짐
숫자 키 병합재인덱싱 — 0부터 순서대로 새로 번호 매겨짐
+ 연산자와 차이+ 는 앞쪽 배열 우선, array_merge는 뒤쪽 배열 우선
recursive 버전충돌 키를 덮어쓰지 않고 서브 배열로 합침
반환값새 배열을 반환, 원본 배열은 변경되지 않음
Tags
#PHP #array_merge #배열병합 #배열합치기 #문자열키 #숫자키 #재인덱싱 #PHP배열함수 #PHP함수 #PHP학습 #웹개발 #티스토리
▼ 티스토리 태그 입력란 복사용
PHP, array_merge, 배열병합, 배열합치기, 문자열키, 숫자키, 재인덱싱, PHP배열함수, PHP함수, PHP학습, 웹개발, 티스토리
댓글