PHP 프로젝트를 진행하면서 외부 API 연동 결과나 복잡한 설정(Config) 데이터처럼 여러 단계로 중첩된 배열(Nested Array) 데이터를 다뤄본 경험이 있을 것이다.
다만 매번 키의 존재 여부를 검증하기 위해 isset()을 무한 반복하거나 Null 합치기 연산자(??)를 남발하다가 코드 가독성이 급격히 떨어지고 예상치 못한 Warning을 마주하는 경우가 많다.
이번에는 닷 점표기법(Dot Notation)을 활용해 아무리 깊은 중첩 배열이라도 안전하게 데이터에 접근할 수 있는 array_get_dot() 서포트 함수를 직접 제작하고, 실무에 적용하는 방법까지 완벽하게 정리해서 소개하겠다.
PHP 7.0 이상부터 지원하는 Null 합치기 연산자(??) 덕분에 배열 키 존재 여부 확인이 과거에 비해 훨씬 간결해진 것은 사실이다.
하지만 중간 단계의 값이 배열이 아니라 null 이거나 스칼라(문자열, 숫자 등) 타입일 때, 중첩 키에 접근하면 PHP 8 버전 이상에서는 TypeError나 Warning 메시지를 발생시킨다.
| 접근 방식 | 안전성 | 가독성 | 중간 노드 Null 처리 |
|---|---|---|---|
| 직접 키 접근 ($arr['a']['b']) | 위험 (Warning/Fatal Error) | 보통 | 불가능 |
| isset() 다중 조건 사용 | 안전함 | 매우 나쁨 (복잡함) | 가능 |
| Null 합치기 연산자 (??) | 부분적 안전 | 양호 | 스칼라 타입 시 경고 발생 가능 |
| array_get_dot() 함수 | 완벽하게 안전함 | 매우 뛰어남 | 기본값(Default)으로 안전 처리 |
우리가 만들 서포트 함수는 문자열로 전달된 경로(예: 'user.profile.name')를 '점(.)' 기준으로 분리하여 배열의 한 단계씩 깊숙이 탐색하도록 구현한다.
탐색 과정에서 중간 데이터가 배열이 아니거나 해당 키가 존재하지 않으면 탐색을 즉시 중단하고 지정된 기본값(Default)을 반환한다.
if (!function_exists('array_get_dot')) {
/**
* 닷 점표기법(Dot Notation)을 이용하여 중첩 배열에서 값을 안전하게 가져오는 서포트 함수
*
* @param array $array 탐색할 대상 배열
* @param string|null $key 닷 점표기법 경로 (예: 'user.profile.name')
* @param mixed $default 키가 존재하지 않거나 잘못된 접근일 경우 반환할 기본값
* @return mixed
*/
function array_get_dot(array $array, ?string $key, $default = null)
{
if (is_null($key) || trim($key) === '') {
return $array;
}
if (array_key_exists($key, $array)) {
return $array[$key];
}
foreach (explode('.', $key) as $segment) {
if (!is_array($array) || !array_key_exists($segment, $array)) {
return $default;
}
$array = $array[$segment];
}
return $array;
}
}
실제 백엔드 API 응답 데이터(JSON을 json_decode하여 배열로 변환한 데이터)를 다루는 실무 예제를 통해 기존 방식과 array_get_dot()의 명확한 차이를 확인해보자.
$response = [
'status' => 200,
'data' => [
'user' => [
'id' => 1042,
'profile' => [
'nickname' => '레드인포',
'avatar' => null
]
]
]
];
✗ 중첩 키가 없거나 데이터 구조가 변경되었을 때 예외가 발생하는 코드다.
// 1. 단순 직접 접근 : address 키가 없으므로 Warning / Undefined array key 발생
$city = $response['data']['user']['address']['city'];
// 2. Null 합치기 연산자 사용 시 : profile이 null이거나 배열이 아니면 PHP 버전별 경고 발생 가능
$avatar = $response['data']['user']['profile']['avatar'] ?? 'default.png';
// avatar가 null이므로 'default.png'가 아닌 null이 그대로 출력되는 의도치 않은 동작 발생!
✓ 서포트 함수를 활용해 예외 상황에서도 안전하고 깔끔하게 기본값을 반환받는 연산 코드다.
// 1. 존재하지 않는 경로 안전하게 추출
$city = array_get_dot($response, 'data.user.address.city', '서울특별시');
// 2. 깊은 경로의 값이 null일 때 기본값 대체 예시
$avatar = array_get_dot($response, 'data.user.profile.avatar') ?? 'default.png';
// 3. 존재하지만 null인 값을 처리해야 하는 경우
$avatarWithDefault = array_get_dot($response, 'data.user.profile.avatar', 'default.png');
if (is_null($avatarWithDefault)) {
$avatarWithDefault = 'default.png';
}
echo $city; // 출력: 서울특별시
echo $avatarWithDefault; // 출력: default.png
서포트 함수를 사용할 때 개발자들이 흔히 착각하거나 놓치기 쉬운 포인트들이 몇 가지 존재한다.
- 실수 1: 단일 키에 점(.) 문자가 포함된 경우
배열 키 자체에 'user.name' 처럼 점이 들어가 있다면 explode()로 인해 키가 분할될 수 있다. 서포트 함수 내에array_key_exists($key, $array)분기문이 선제적으로 포함되어 있어 1차 차단은 되지만, 2단계 깊이 이상에서 키 자체에 점이 있다면 경로 탐색 실패의 원인이 된다. 배열 키 이름을 정할 때는 점 사용을 피해야 한다. - 실수 2: null 값과 존재하지 않는 키의 혼동
키가 아예 존재하지 않는 경우와, 키는 존재하지만 값으로 null이 할당되어 있는 경우는 엄연히 다르다. 위 구현체는 키가 존재하고 그 값이 null인 경우 해당 null을 반환한다. 기본값이 반환되길 원한다면 반환 후 추가 검증을 수행하는 것이 안전하다.
array_get_dot() 서포트 함수는 깊은 배열 구조를 처리할 때 방어적인 코드를 작성할 수 있는 매우 핵심적인 유틸리티다. 소소한 유틸리티 함수의 도입이라는 작은 습관이 모여 서비스 전체의 안정성을 높여준다는 점을 잊지 말자. 이 글의 실전 코드를 프로젝트의 공통 서포트 함수 파일(helpers.php)에 추가해 즉시 활용해보면, 더 이상 배열 키 접근 오류로 인한 에러 로그에 시달리지 않을 것이다.