PHP 8 이상에서 갑자기 나타나는 "Trying to access array offset on value of type null" 경고를 봤을까? 구 버전에서는 아무 문제 없던 코드가 업그레이드 후 작동을 멈춘다. 다만 대부분의 개발자들은 이 에러가 정확히 뭘 의미하는지, 왜 갑자기 뜨는지, 어떻게 고쳐야 하는지 혼란스러워한다. 이번에는 이 에러의 정확한 원인, PHP 버전별 동작 차이, 그리고 실전에서 써먹을 수 있는 완벽한 해결책을 정리해서 소개하겠다.

 

1단계: PHP 8에서 뭐가 바뀌었나?

PHP 8 이전에는 null 값에 배열 인덱스로 접근해도 경고 없이 null을 반환했다. 하지만 PHP 8부터는 이런 "위험한 동작"을 명시적으로 경고한다. 쉽게 말해서, 존재하지 않을 수 있는 데이터를 마치 배열인 것처럼 접근하는 건 버그의 신호라는 뜻이다.

 

문제가 발생하는 전형적인 상황

✗ 잘못된 코드 (PHP 8에서 경고 발생):

<?php
$user = null; // 예: 데이터베이스 조회 결과 없음
echo $user['name']; // Warning: Trying to access array offset on value of type null
?>

또는 함수가 null을 반환할 때:

<?php
function getUserData() {
    // 조건에 따라 배열 또는 null 반환
    return null;
}

$result = getUserData();
echo $result['email']; // Warning: Trying to access array offset on value of type null
?>

 

2단계: 실전 해결책 - 5가지 방법

 

방법 1: null 체크 (가장 명시적)

✓ 올바른 코드:

<?php
$user = getUserFromDB(1);

if ($user !== null) {
    echo $user['name'];
} else {
    echo 'User not found';
}
?>

장점: 의도가 명확하고 버그를 쉽게 발견할 수 있다. 단점: 코드가 길어진다.

 

방법 2: isset() 함수 (가장 간결)

✓ 올바른 코드:

<?php
$user = getUserFromDB(1);

if (isset($user['name'])) {
    echo $user['name'];
} else {
    echo 'Name not available';
}
?>

동작: null이거나 인덱스가 없으면 false를 반환한다. 가장 실무에서 자주 쓰인다.

 

방법 3: Null Coalescing 연산자 ?? (PHP 7+, 권장)

✓ 올바른 코드:

<?php
$user = getUserFromDB(1);

// 한 줄로 처리: null이면 기본값 반환
echo $user['name'] ?? 'Unknown';

// 중첩된 배열도 안전하게
echo $user['profile']['bio'] ?? 'No bio';
?>

장점: 간결하고 기본값 설정이 쉽다. 이것이 현대 PHP의 표준이다.

 

방법 4: 함수 반환값 보장 (근본 해결)

✓ 올바른 코드:

<?php
function getUserData($id) {
    // null이 아니라 빈 배열 반환
    $user = $db->query("SELECT * FROM users WHERE id = ?", [$id]);
    return $user ?: []; // null이면 빈 배열 반환
}

$user = getUserData(1);
echo $user['name'] ?? 'Not found'; // 항상 안전
?>

장점: 함수 호출부에서 매번 체크할 필요가 없다. 설계 단계에서 문제를 해결한다.

 

방법 5: 타입 힌트로 예방 (PHP 7.1+)

✓ 올바른 코드:

<?php
// 함수가 절대 null을 반환하지 않도록 보장
function getUserData($id): array {
    $user = $db->query("SELECT * FROM users WHERE id = ?", [$id]);
    return $user ?? []; // 타입이 맞지 않으면 TypeError 발생
}

$user = getUserData(1);
echo $user['name']; // 이제 안전함
?>

장점: IDE 자동완성이 정확해지고, 타입 불일치를 컴파일 단계에서 잡는다.

 

3단계: 실전 예제 - API 응답 처리

API에서 받은 JSON 데이터를 처리할 때 이 에러가 자주 발생한다:

✗ 잘못된 코드:

<?php
$response = json_decode($apiData, true); // null일 수 있음
echo $response['user']['email']; // 에러 위험
?>

✓ 올바른 코드 (추천):

<?php
$response = json_decode($apiData, true);

// 방법 A: 단계별 체크
if (!$response || !isset($response['user']) || !isset($response['user']['email'])) {
    throw new Exception('Invalid API response');
}
echo $response['user']['email'];

// 방법 B: Null Coalescing 연산자 (더 간결)
$email = $response['user']['email'] ?? null;
if ($email === null) {
    throw new Exception('Email not found in API response');
}
echo $email;

// 방법 C: 헬퍼 함수로 깔끔하게
function getNestedValue($array, $path, $default = null) {
    $keys = explode('.', $path);
    $value = $array;
    foreach ($keys as $key) {
        if (!is_array($value) || !isset($value[$key])) {
            return $default;
        }
        $value = $value[$key];
    }
    return $value;
}

$email = getNestedValue($response, 'user.email', 'no-email@example.com');
echo $email; // 안전함
?>

 

4단계: 주의사항 - 흔한 실수
실수 문제 올바른 방법
✗ empty($array['key']) 0이나 빈 문자열도 false 처리됨 ✓ isset($array['key']) 또는 array_key_exists()
✗ @$array['key'] (@ 억제) 에러만 숨길 뿐 실제 문제 해결 안 됨 ✓ isset() 또는 ?? 연산자로 명시적으로
✗ (array)$data 강제 캐스팅 타입이 섞여서 더 복잡해짐 ✓ is_array() 체크 후 접근
✗ if ($array) 존재 체크 빈 배열도 false이므로 부정확 ✓ isset() 또는 array_key_exists()

 

5단계: PHP 버전별 에러 메시지

같은 코드라도 버전에 따라 다르게 처리된다:

PHP 버전 동작 에러/경고
PHP 7.0 이하 null['key'] → null 반환 경고 없음 (위험)
PHP 7.1~7.4 null['key'] → null 반환 Notice: Trying to access offset on value of type null
PHP 8.0+ null['key'] → null 반환 Warning: Trying to access array offset on value of type null

 

마무리: 작은 습관이 버그를 없앤다

"Trying to access array offset on value of type null"은 PHP 8이 개발자의 부주의를 잡아내려는 신호다. 이 에러는 코드의 약한 부분을 드러내고, 버그가 프로덕션에 가기 전에 발견하도록 도와준다. 단순히 경고를 무시하거나 @ 기호로 억제하는 것이 아니라, isset()이나 ?? 연산자로 명시적으로 처리하는 습관이 모여서 견고한 코드를 만든다는 점을 잊지 말자. 이 글의 "방법 3: Null Coalescing 연산자"를 기본으로 삼고, 함수 반환값에 타입 힌트를 추가하면, 앞으로 이런 에러에서 자유로워질 것이다.