Menu

PHP json_encode(): 배열과 객체를 JSON으로 변환

json_encode($value)는 PHP 배열, 객체, 스칼라를 JSON 문자열로 바꿉니다. 연관 배열은 JSON 객체가, 리스트는 JSON 배열이 되며, JSON_PRETTY_PRINT와 JSON_UNESCAPED_UNICODE 같은 플래그가 출력을 제어합니다.

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

json_encode($value)는 PHP 값에 대한 JSON 텍스트를 반환합니다. 연관 배열은 JSON 객체가, 리스트(키 0, 1, 2...)는 JSON 배열이 되며, 문자열, 숫자, true, false, null은 대응하는 JSON 값이 됩니다.

출력:

{"name":"Ada","age":36,"langs":["php","js"],"admin":true,"manager":null}
string

결과는 평범한 문자열이며, 브라우저로 보내거나, 파일이나 데이터베이스 컬럼에 저장하거나, 다른 프로그램에 넘길 수 있습니다. JSON을 다시 PHP로 바꾸려면 json_decode()를 쓰세요.

JSON 보기 좋게 출력하기

json_encode()는 두 번째 인수로 플래그를 받습니다. JSON_PRETTY_PRINT는 줄바꿈과 공백 4칸 들여쓰기를 추가하며, 설정 파일이나 디버그 로그에 원하는 형태입니다. 여러 플래그는 |로 조합하세요.

출력:

{
    "app": "shop",
    "debug": false,
    "db": {
        "host": "localhost",
        "port": 3306
    },
    "tags": []
}

한글, 일본어 등 UTF-8 텍스트를 읽을 수 있게 유지하기

기본적으로 json_encode()는 ASCII가 아닌 모든 문자를 \u 이스케이프로 쓰고 모든 / 앞에 백슬래시를 붙입니다. 둘 다 올바른 JSON이고 같은 텍스트로 디코딩되지만, 출력을 읽기 어렵고 길게 만듭니다. JSON_UNESCAPED_UNICODE는 문자를 유지하고, JSON_UNESCAPED_SLASHES는 URL을 그대로 유지합니다.

출력:

{"name":"\u308a\u3093\u3054","price":120,"url":"https:\/\/example.com\/fruit\/apple"}
{"name":"りんご","price":120,"url":"https://example.com/fruit/apple"}

디코딩한 뒤 한글이나 일본어 텍스트가 깨져 보인다면(문자 깨짐) 문제는 이스케이프가 아닙니다. 문자열이 처음부터 UTF-8이 아니었던 것입니다. json_encode()는 UTF-8만 받고 그 밖의 것에는 false를 반환하며, 에러에 관한 절에서 보여 줍니다.

배열이 리스트 대신 객체가 될 때

PHP 배열은 키가 정확히 0, 1, 2... 순서일 때만 JSON 배열로 인코딩됩니다. 다른 키가 있으면 JSON 객체가 됩니다. 키에 빈틈을 남기는 unset()이나 array_filter() 뒤에 사람들이 여기에 걸립니다.

출력:

{"0":"apple","2":"cherry"}
["apple","cherry"]
{"1":"a","2":"b"}
[]
{}
{"0":"a","1":"b"}

받는 코드가 리스트를 기대한다면 인코딩 전에 항상 array_values()를 호출하세요. 비어 있을 수 있는 객체를 기대한다면 빈 값도 {}로 나오도록 new stdClass()나 (object) $array를 쓰세요.

객체 인코딩과 JsonSerializable로 JSON 제어하기

일반 객체는 public 속성만으로 인코딩되며, protected와 private 속성은 건너뜁니다. 객체가 JSON에서 어떻게 보일지 정확히 정하려면 JsonSerializable 인터페이스를 구현하고 jsonSerialize()에서 데이터를 반환하세요.

출력:

{"name":"Ada","nick":null}
{"date":"2026-03-14 09:30:00.000000","timezone_type":3,"timezone":"UTC"}
{
    "id": 7,
    "total": 19.5,
    "created": "2026-03-14T09:30:00+00:00"
}

enum Status: string 같은 backed enum은 그 값("active")으로 인코딩됩니다. 순수 enum에는 값이 없으므로 json_encode()가 "Non-backed enums have no default serialization"과 함께 실패합니다.

숫자, 실수, 숫자 문자열

정수와 실수는 JSON 숫자로 쓰이고, 문자열은 숫자가 들어 있어도 문자열로 남습니다. 세 가지 플래그가 이를 바꿉니다.

출력:

{"price":10}
{"price":10.0}
0.30000000000000004
{"qty":"3","id":"007"}
{"qty":3,"id":7}

JSON_NUMERIC_CHECK는 모든 숫자 문자열을 변환하므로 "007" 같은 ID나 "01234" 같은 우편번호가 앞자리 0을 잃습니다. 배열 전체에 쓰지 말고 원하는 필드만 (int)로 변환하세요.

json_encode가 false를 반환할 때: 에러 찾기

json_encode()는 값을 인코딩할 수 없으면 false를 반환합니다. 흔한 원인은 올바른 UTF-8이 아닌 문자열(오래된 파일이나 Latin-1 데이터베이스에서 읽은 텍스트)과 실수 값 NAN, INF입니다. json_last_error_msg()는 무엇이 잘못되었는지 알려 주고, JSON_THROW_ON_ERROR는 대신 JsonException을 던지게 합니다.

출력:

bool(false)
Malformed UTF-8 characters, possibly incorrectly encoded
{"name":"Caf\ufffd"}
{"name":"Café"}
JsonException: Inf and NaN cannot be JSON encoded

새 코드에서는 JSON_THROW_ON_ERROR가 더 나은 기본값입니다. 아무도 확인하지 않는 false는 결국 빈 문자열로 저장되거나 전송됩니다.

PHP API에서 JSON 반환하기

JSON으로 응답하는 PHP 스크립트는 무엇이든 출력하기 전에 Content-Type 헤더를 설정하고, 한 번 인코딩하고, 멈춥니다.

<?php
header('Content-Type: application/json; charset=utf-8');

$products = [
    ['id' => 1, 'name' => 'りんご', 'price' => 120],
    ['id' => 2, 'name' => 'みかん', 'price' => 80],
];

echo json_encode(['data' => $products], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
exit;

대신 HTML <script> 태그 안에 JSON을 출력한다면 JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT를 추가하세요. 기본 슬래시 이스케이프는 </script>를 <\/script>로 바꾸지만, 누군가 JSON_UNESCAPED_SLASHES를 추가하는 순간 그 보호는 사라지고, 값 안의 <!--는 여전히 브라우저가 스크립트를 해석하는 방식을 바꿉니다. 이 플래그들은 <, >, &, ', "를 \u003C, \u003E, \u0026, \u0027, \u0022로 쓰며, JavaScript는 이를 같은 문자로 읽습니다.

자주 묻는 질문

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

json_encode()에 넘기세요: json_encode(['name' => 'Ada', 'age' => 36])는 {"name":"Ada","age":36}을 반환합니다. 키가 0, 1, 2... 순서인 배열은 대신 JSON 배열이 됩니다: json_encode(['a', 'b'])는 ["a","b"]를 반환합니다.

PHP에서 JSON을 보기 좋게 출력하려면 어떻게 하나요?

JSON_PRETTY_PRINT 플래그를 추가하세요. json_encode($data, JSON_PRETTY_PRINT)는 공백 4칸으로 들여쓰고 각 값을 한 줄씩 둡니다. 플래그는 |로 조합합니다. 예: JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE.

json_encode가 한글이나 일본어 텍스트를 \u 코드로 바꾸는 이유는 무엇인가요?

기본적으로 ASCII가 아닌 모든 문자는 \uXXXX 이스케이프로 쓰이므로 りんご는 \u308a\u3093\u3054가 됩니다. 여전히 올바른 JSON이지만, 문자를 읽을 수 있게 유지하려면 JSON_UNESCAPED_UNICODE를 넘기세요.

json_encode가 false를 반환하는 이유는 무엇인가요?

보통 문자열이 올바른 UTF-8이 아니거나 데이터에 NAN이나 INF가 들어 있기 때문입니다. 이유를 보려면 json_last_error_msg()를 호출하거나, false를 반환하는 대신 JsonException을 던지도록 JSON_THROW_ON_ERROR를 넘기세요.

빈 배열에 대해 json_encode가 [] 대신 {}를 출력하게 하려면 어떻게 하나요?

빈 PHP 배열은 항상 []로 인코딩됩니다. 빈 객체에는 new stdClass()나 (object) []를 쓰거나, 값 안의 모든 배열을 객체로 바꾸는 JSON_FORCE_OBJECT 플래그를 쓰세요.

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

Coddy로 코딩 배우기

시작하기