중첩된 다차원 배열의 특정 깊이에 있는 값을 변경하려다가 Undefined array key 경고를 보거나 배열 구조가 꼬여서 고생해본 경험이 있는가?
개발하다 보면 API 응답이나 설정 파일 데이터를 다룰 때 깊은 레이어의 키값을 변경해야 하는 상황이 자주 발생한다. 다만 대부분의 개발자들은 foreach 루프를 복잡하게 중첩시키거나, 매번 isset으로 키의 존재 여부를 일일이 검사하며 더러운 코드를 작성하곤 한다.
이번에는 점 표기법(dot notation)으로 다차원 배열의 값을 안전하게 수정하는 array_set() 서포트 함수가 정확히 무엇인지, 왜 필요한지, 그리고 어떻게 작성하고 활용하는지 완벽하게 정리해서 소개하겠다.

 

1. PHP 다차원 배열 데이터 수정의 한계와 array_set() 개념

PHP에서 다차원 배열의 깊은 곳에 있는 값을 수정하려면 $array['user']['profile']['name'] = '홍길동'; 형태로 직접 접근해야 한다. 문제는 중간 경로에 해당하는 키가 배열 형태로 존재하지 않으면 PHP가 E_WARNING 경고를 발생시키거나 의도치 않은 타입 변환을 일으킨다는 점이다.
특히 동적으로 생성되는 폼 데이터나 외부 JSON API 파싱 결과를 다룰 때, 특정 경로의 키가 없는 상태에서 값을 할당하면 예외가 터지거나 null 참조 에러가 일어난다.
라라벨(Laravel) 같은 프레임워크에서는 Arr::set() 서포트 함수를 제공하여 "user.profile.name" 형태로 안전하게 값을 삽입하거나 수정한다. 순수 PHP(Vanilla PHP) 환경에서도 이와 동일한 동작을 하는 array_set() 서포트 함수를 구현해두면 코드의 안정성과 가독성을 획기적으로 높일 수 있다.

 

2. array_set() 서포트 함수 비교 및 동작 메커니즘

중첩된 배열 구조 변경을 처리하는 방식에 따라 기존 방식과 서포트 함수 방식의 차이를 비교해보자.

구분직접 키 할당 ($array['a']['b'])array_set() 서포트 함수 ($array, 'a.b', $val)
부모 키 미존재시Undefined array key 경고 발생 및 오류 위험부모 키를 자동으로 빈 배열로 생성하며 안전 할당
동적 경로 수정문자열 경로 파싱 불가 (코드 고정 필요)'user.settings.theme' 같은 동적 문자열 지원
코드 가독성isset 체크와 대괄호 중첩으로 지저분함단 한 줄의 서포트 함수 호출로 명확함
참조(Reference) 활용불가 또는 번거로움배열의 원본을 참조 전달(&)하여 제자리 수정 가능

 

3. array_set() 서포트 함수 실전 구현과 적용 예제

이제 직접 참조 메모리 주소를 탐색하는 방식을 이용해 array_set() 서포트 함수를 구현해보자. 탐색 대상 배열을 참조변수(&$array)로 받아서 점(.)을 기준으로 분할한 뒤 차례대로 깊이를 좁혀나가는 방식이다.

 

array_set() 서포트 함수 완성 코드
<?php
/**
 * 점 표기법(dot notation)을 이용하여 다차원 배열에 값을 안전하게 설정합니다.
 *
 * @param array $array 대상 배열 (참조 전달)
 * @param string|null $key 점 표기법 키 (예: 'user.profile.name')
 * @param mixed $value 설정할 값
 * @return array
 */
function array_set(array &$array, ?string $key, mixed $value): array
{
    if ($key === null) {
        return $array = $value;
    }

    $keys = explode('.', $key);
    $current = &$array;

    while (count($keys) > 1) {
        $segment = array_shift($keys);

        if (!isset($current[$segment]) || !is_array($current[$segment])) {
            $current[$segment] = [];
        }

        $current = &$current[$segment];
    }

    $current[array_shift($keys)] = $value;

    return $array;
}
?>

위 코드에서 가장 중요한 핵심은 $current = &$current[$segment]; 부분이다. 원본 배열의 참조를 유지하면서 깊은 단계로 이동하기 때문에, 부모 키가 없더라도 자동으로 빈 배열을 만들면서 안전하게 뎁스를 파고 들어간다.

 

실무 적용 예제: 사용자 옵션 데이터 동적 업데이트
<?php
// 기존 유저 설정 데이터
$userConfig = [
    'user' => [
        'id' => 42,
        'profile' => [
            'nickname' => 'developer'
        ]
    ]
];

// 1. 기존에 있던 깊은 값 수정
array_set($userConfig, 'user.profile.nickname', 'redinfo');

// 2. 존재하지 않는 중간 경로와 값 동적 추가
array_set($userConfig, 'user.settings.notifications.email', true);

var_dump($userConfig);
?>

출력 결과는 다음과 같이 원본 배열 구조가 안전하고 정확하게 확장 변경된다.

array(1) {
  ["user"]=>
  array(3) {
    ["id"]=>
    int(42)
    ["profile"]=>
    array(1) {
      ["nickname"]=>
      string(7) "redinfo"
    }
    ["settings"]=>
    array(1) {
      ["notifications"]=>
      array(1) {
        ["email"]=>
        bool(true)
      }
    }
  }
}

 

4. 자주 하는 실수와 주의사항

array_set() 함수를 작성하거나 사용할 때 흔히 저지르는 실수를 짚어보자.

✗ 잘못된 예제: 참조(&) 키워드를 빠뜨려 원본 배열이 변경되지 않는 경우
배열 파라미터에 array &$array 형태의 참조(Reference) 선언을 빼먹으면 함수 내부에서만 배열이 수정되고 호출한 곳의 원본 변수에는 아무런 변화가 일어나지 않는다.

<?php
// ✗ 잘못된 코드 (참조 전달 누락)
function array_set_wrong(array $array, string $key, mixed $value): array {
    $keys = explode('.', $key);
    // ... 내부 값 변경 처리
    return $array;
}

$data = ['a' => 1];
array_set_wrong($data, 'a.b.c', 'test');
// $data는 수정되지 않고 ['a' => 1] 상태로 남아있음
?>
<?php
// ✓ 올바른 코드 (참조 전달 적용)
function array_set_correct(array &$array, string $key, mixed $value): array {
    $keys = explode('.', $key);
    $current = &$array;
    // ... 원본 배열 참조 주소를 탐색하며 변경
    return $array;
}

$data = ['a' => 1];
array_set_correct($data, 'a.b.c', 'test');
// $data 원본 데이터가 'a.b.c' 키를 포함하도록 정상 갱신됨
?>

✗ 잘못된 예제: 기존의 스칼라(문자열/숫자) 값 경로를 배열로 덮어쓸 때의 데이터 손실
경로 중간에 이미 스칼라 값(예: 'user.profile' = 'simple_string')이 자리 잡고 있는데 array_set($data, 'user.profile.name', 'john')을 실행하면 이전의 문자열 데이터는 덮어씌워져 배열로 변환된다. 기존 데이터 타입 손실이 우려된다면 사전에 is_array 검사를 추가해야 한다.

 

5. 정리 및 결론

PHP 다차원 배열을 다룰 때 array_set() 서포트 함수 도입은 복잡한 데이터 조작의 안전성을 확보해주는 필수적인 최적화다. 가독성 높은 헬퍼 함수를 구축해두는 작은 습관이 모여서 견고한 백엔드 아키텍처라는 큰 효과를 만든다는 점을 잊지 말자. 이 글의 실전 구현 코드를 참고해 프로젝트 서포트 헬퍼 모듈에 추가하고 사용해보면, 꼬여버린 다차원 배열 처리 로직에서 완전히 벗어날 수 있을 것이다.