Menu

PHP json_decode(): JSON을 배열이나 객체로 파싱

json_decode($json, true)는 JSON 문자열을 PHP 연관 배열로 바꾸며, true가 없으면 stdClass 객체를 얻습니다. 중첩된 값, JSON_THROW_ON_ERROR로 에러 처리, json_validate(), json_decode가 null을 반환하는 이유를 알아봅니다.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

json_decode($json, true)는 JSON 문자열을 PHP 값으로 바꾸며, 모든 JSON 객체가 연관 배열이 됩니다. true를 생략하면 JSON 객체는 대신 ->로 읽는 stdClass 객체가 됩니다. 잘못된 JSON은 null을 줍니다.

출력:

Ada
js
Ada
php
Array
(
    [name] => Ada
    [age] => 36
    [langs] => Array
        (
            [0] => php
            [1] => js
        )

    [admin] => 1
)

JSON 배열은 어느 모드를 고르든 항상 PHP 리스트가 됩니다. 반대 방향, 즉 PHP에서 JSON으로 가는 것은 json_encode()입니다.

연관 배열 또는 객체: true와 false

두 모드는 같은 데이터를 담습니다. 코드에서 더 읽기 좋은 쪽을 고르세요. 배열은 모든 배열 함수(array_column, array_map, isset($data['key']))와 동작하므로 대부분의 코드는 true를 넘깁니다. 객체에서는 하이픈이나 숫자가 든 키처럼 올바른 속성 이름이 아닌 키에 중괄호 문법이 필요합니다.

출력:

Ada zero London
Ada zero London
object(stdClass)#2 (1) {
  ["city"]=>
  string(6) "London"
}

네 번째 매개변수는 플래그를 받습니다. JSON_OBJECT_AS_ARRAY도 배열을 주지만, 두 번째 인수가 null(기본값)일 때만입니다. json_decode($json, flags: JSON_OBJECT_AS_ARRAY)는 배열을 반환하고, json_decode($json, false, 512, JSON_OBJECT_AS_ARRAY)는 여전히 객체를 반환합니다.

중첩된 JSON 반복하기

API 응답은 보통 객체 안의 객체 리스트입니다. 한 번 디코딩한 다음 foreach로 순회하고, 없을 수 있는 필드에는 ??를 쓰세요.

출력:

#1 Ada <ada@example.com> roles: admin, editor
#2 Linus <no email> roles: none
#3 Grace <grace@example.com> roles: editor
Array
(
    [1] => Ada
    [2] => Linus
    [3] => Grace
)

잘못된 JSON 처리하기

json_decode()는 잘못된 JSON에 null을 반환하지만, null은 JSON 텍스트 null의 올바른 결과이기도 하므로 null만으로는 실패했는지 알 수 없습니다. json_last_error_msg()는 마지막 호출의 이유를 줍니다. 더 깔끔한 방법은 JsonException을 던지는 JSON_THROW_ON_ERROR입니다.

출력:

NULL
Syntax error
NULL
No error
Invalid JSON: Syntax error

세 번째 인수 512는 최대 중첩 깊이(기본값)입니다. 이름 있는 인수를 쓰면 건너뛸 수 있습니다: json_decode($json, true, flags: JSON_THROW_ON_ERROR).

json_validate()로 문자열이 올바른 JSON인지 확인하기

PHP 8.3은 json_validate()를 추가했습니다. 디코딩된 배열을 만들지 않고 true나 false로 답하므로, 요청 본문을 일찍 거부할 때처럼 예, 아니요만 필요할 때 디코딩보다 메모리를 덜 씁니다.

출력:

'{"a": 1}'    valid
'[1, 2, 3]'   valid
'"text"'      valid
'{a: 1}'      invalid: Syntax error
'{\'a\': 1}'  invalid: Syntax error
''            invalid: Syntax error

어차피 데이터를 쓸 거라면 json_validate()를 건너뛰고 JSON_THROW_ON_ERROR로 디코딩하세요. 먼저 검증하면 문자열을 두 번 파싱합니다.

JSON 파일 읽기

file_get_contents()로 파일을 읽고 문자열을 디코딩하세요. 이 블록은 읽을 파일이 있도록 먼저 settings.json을 씁니다.

출력:

Theme: dark
Plugins: 2
{
    "theme": "dark",
    "fontSize": 16,
    "plugins": [
        "git",
        "lint"
    ]
}

json_decode가 null을 반환하는 흔한 원인

JSON은 JavaScript나 PHP 배열 문법보다 엄격합니다. 아래 문자열은 모두 그럴듯해 보이지만 모두 null을 반환합니다. 실행해서 각각의 이유를 확인한 다음 하나를 고치고 다시 실행해 보세요.

출력:

single quotes    Syntax error
unquoted key     Syntax error
trailing comma   Syntax error
comment          Syntax error
byte order mark  Syntax error
too deep         Maximum stack depth exceeded
float(1.2345678901234567E+19)
string(20) "12345678901234567890"

바이트 순서 표시는 대부분의 에디터에서 보이지 않으며, JSON 파일이 "멀쩡해 보이는데" 디코딩되지 않는 고전적인 이유입니다. 디코딩 전에 $text = preg_replace('/^\xEF\xBB\xBF/', '', $text);로 제거하세요.

자주 묻는 질문

PHP에서 JSON을 배열로 변환하려면 어떻게 하나요?

두 번째 인수로 true를 넘기세요: json_decode('{"name":"Ada"}', true)는 ['name' => 'Ada']를 반환하므로 $data['name']으로 값을 읽습니다. true가 없으면 JSON 객체는 stdClass 객체가 되고 $data->name으로 씁니다.

json_decode가 null을 반환하는 이유는 무엇인가요?

JSON이 잘못되었거나(작은따옴표, 끝의 쉼표, 따옴표 없는 키, 바이트 순서 표시), 깊이 제한보다 깊게 중첩되었거나, JSON이 정말 null이기 때문입니다. json_last_error_msg()를 확인하거나, JSON_THROW_ON_ERROR로 디코딩해 이유가 담긴 JsonException을 받으세요.

PHP에서 문자열이 올바른 JSON인지 확인하려면 어떻게 하나요?

PHP 8.3부터 json_validate($string)가 디코딩된 값을 만들지 않고 true나 false를 반환합니다. 이전 버전에서는 디코딩한 뒤 json_last_error() === JSON_ERROR_NONE을 확인하세요.

PHP에서 JSON 파일을 읽으려면 어떻게 하나요?

파일을 읽은 다음 디코딩하세요: $data = json_decode(file_get_contents('data.json'), true, flags: JSON_THROW_ON_ERROR);. 파일이 없으면 file_get_contents()가 false를 반환하므로 먼저 그것을 확인하세요.

PHP에서 하이픈이 든 JSON 키에 접근하려면 어떻게 하나요?

배열로 디코딩해 $data['first-name']을 쓰거나, 객체라면 중괄호를 쓰세요: $obj->{'first-name'}. 같은 중괄호 문법은 $obj->{'0'}처럼 숫자인 키에도 동작합니다.

Coddy 프로그래밍 언어 일러스트

Coddy로 코딩 배우기

시작하기