수색…


소개

JSON ( JavaScript Object Notation )은 객체를 일반 텍스트로 직렬화하는 플랫폼 및 언어 독립적 인 방식입니다. PHP는 웹에서 자주 사용되기 때문에 PHP에서 JSON을 사용하기위한 기본 확장 이 있습니다.

통사론

  • 문자열 json_encode (혼합 $ 값 [, int $ 옵션 = 0 [, int $ 깊이 = 512]])
  • 혼합 된 json_decode (string $ json [, bool $ assoc = false [, int $ depth = 512 [, int $ options = 0]]])

매개 변수

매개 변수 세부
json_encode -
인코딩되는 값입니다. 자원을 제외한 모든 유형이 될 수 있습니다. 모든 문자열 데이터는 UTF-8로 인코딩되어야합니다.
옵션들 비트 마스크는 JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_APOS, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_PRESERVE_ZERO_FRACTION, JSON_UNESCAPED_UNICODE, JSON_PARTIAL_OUTPUT_ON_ERROR로 구성됩니다. 이 상수의 동작은 JSON 상수 페이지에 설명되어 있습니다.
깊이 최대 깊이를 설정하십시오. 0보다 커야합니다.
json_decode -
json json 문자열이 디코딩되고 있습니다. 이 함수는 UTF-8로 인코딩 된 문자열에서만 작동합니다.
어록 함수가 객체 대신 연관 배열을 반환해야합니다.
옵션들 JSON 디코드 옵션의 비트 마스크. 현재 JSON_BIGINT_AS_STRING 만 지원됩니다 (기본값은 큰 정수를 실수로 형 변환하는 것입니다)

비고

  • json_decode 가 무효 인 JSON을 처리하는 것은 매우 희한한 일이며, 해독이 성공했는지를 신뢰성있게 결정하는 것은 매우 어렵습니다. json_decode는 유효하지 않은 입력에 대해 null을 반환합니다. 이러한 문제를 방지하려면 사용할 때마다 항상 json_last_error를 호출해야합니다.

JSON 문자열 디코딩

json_decode() 함수는 JSON 인코딩 문자열을 첫 번째 매개 변수로 사용하여 PHP 변수로 파싱합니다.

일반적으로 json_decode() 는 JSON 객체의 최상위 항목이 사전이거나 JSON 객체가 배열 인 경우 인덱싱 된 배열 인 경우 \ stdClass객체를 반환합니다. 또한 단순 문자열, "true" , "false""null" 과 같은 특정 스칼라 값에 대해 스칼라 값 또는 NULL 을 반환합니다. 또한 오류가 발생할 때마다 NULL 을 반환 NULL .

// Returns an object (The top level item in the JSON string is a JSON dictionary)
$json_string = '{"name": "Jeff", "age": 20, "active": true, "colors": ["red", "blue"]}';
$object = json_decode($json_string);
printf('Hello %s, You are %s years old.', $object->name, $object->age);
#> Hello Jeff, You are 20 years old.

// Returns an array (The top level item in the JSON string is a JSON array)
$json_string = '["Jeff", 20, true, ["red", "blue"]]';
$array = json_decode($json_string);
printf('Hello %s, You are %s years old.', $array[0], $array[1]);

위에서 디코딩 한 객체의 각 속성의 유형과 값을 보려면 var_dump() 를 사용하십시오.

// Dump our above $object to view how it was decoded
var_dump($object);

출력 (변수 유형 참고) :

class stdClass#2 (4) {
 ["name"] => string(4) "Jeff"
 ["age"] => int(20)
 ["active"] => bool(true)
 ["colors"] =>
   array(2) {
     [0] => string(3) "red"
     [1] => string(4) "blue"
   }
}

참고 : JSON의 변수 유형 이 해당 PHP로 변환되었습니다.


객체를 반환하는 대신 JSON 객체의 연관 배열 을 반환하려면 truejson_decode()두 번째 매개 변수 로 전달하십시오.

$json_string = '{"name": "Jeff", "age": 20, "active": true, "colors": ["red", "blue"]}';
$array = json_decode($json_string, true); // Note the second parameter
var_dump($array);

출력 (배열 연관 구조에 주목하십시오) :

array(4) {
  ["name"] => string(4) "Jeff"
  ["age"] => int(20)
  ["active"] => bool(true)
  ["colors"] =>
  array(2) {
    [0] => string(3) "red"
    [1] => string(4) "blue"
  }
}

반환 될 변수가 객체가 아닌 경우 두 번째 매개 변수 ( $assoc )는 아무 효과가 없습니다.

참고 : $assoc 매개 변수를 사용하면 빈 배열과 빈 객체를 구분하지 않게됩니다. 즉, 디코딩 된 출력에서 json_encode() 를 다시 실행하면 JSON 구조가 달라집니다.

재귀에서 JSON 문자열의 요소가 512 개 (5.2.3 이전 버전에서는 20 개, 버전 5.2.3에서는 128 개) "깊이"인 경우 json_decode() 함수는 NULL 반환 NULL . 버전 5.3 이상에서는 아래에 설명 된 것처럼 세 번째 매개 변수 ( $depth )를 사용하여이 제한을 제어 할 수 있습니다.


설명서에 따르면 :

PHP는 원본 »RFC 4627에 명시된대로 JSON의 상위 집합을 구현합니다. 또한 스칼라 유형과 NULL을 인코딩하고 디코딩합니다. RFC 4627은 배열이나 객체 내에 중첩 될 때만이 값을 지원합니다. 이 수퍼 세트가 최신 »RFC 7159 (RFC 4627을 대체하는 것을 목표로 함) 및 »ECMA-404 의 "JSON 텍스트"의 확장 된 정의와 일치하지만이 경우 RFC 4627을 엄격히 준수하는 이전 JSON 파서와의 상호 운용성 문제가 발생할 수 있습니다. 단일 스칼라 값을 인코딩합니다.

즉, 예를 들어, 간단한 문자열은 PHP에서 유효한 JSON 객체로 간주됩니다.

$json = json_decode('"some string"', true);
var_dump($json, json_last_error_msg());

산출:

string(11) "some string"
string(8) "No error"

그러나 배열이나 객체가 아닌 단순 문자열은 RFC 4627 표준의 일부가 아닙니다. 결과적으로 JSLint , JSON Formatter & Validator (RFC 4627 모드)와 같은 온라인 체커는 오류를 줄 것입니다.

재귀 깊이 (기본값은 512 )에 대한 세 번째 $depth 매개 변수가 있습니다.이 매개 변수는 원래 개체 내부에서 중첩 된 개체의 양을 의미합니다.

네 번째 $options 매개 변수가 있습니다. 현재 하나의 값인 JSON_BIGINT_AS_STRING 만 허용합니다. 이 옵션을 벗어나는 기본 동작은 문자열 대신 큰 정수를 부동 소수점 형으로 캐스팅하는 것입니다.

true, false 및 null 리터럴 중 소문자가 아닌 소문자 변형은 유효한 입력으로 더 이상 허용되지 않습니다.

그래서이 예제 :

var_dump(json_decode('tRue'), json_last_error_msg());
var_dump(json_decode('tRUe'), json_last_error_msg());
var_dump(json_decode('tRUE'), json_last_error_msg());
var_dump(json_decode('TRUe'), json_last_error_msg());
var_dump(json_decode('TRUE'), json_last_error_msg());
var_dump(json_decode('true'), json_last_error_msg());

PHP 5.6 이전 :

bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"

그리고 이후 :

NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
bool(true)
string(8) "No error"

falsenull 대해서도 비슷한 문제가 발생합니다.

json_decode() 는 문자열을 변환 할 수없는 경우 NULL 을 반환 NULL .

$json = "{'name': 'Jeff', 'age': 20 }" ;  // invalid json 

$person = json_decode($json);
echo $person->name;    //  Notice: Trying to get property of non-object: returns null
echo json_last_error();     
#  4 (JSON_ERROR_SYNTAX)
echo json_last_error_msg(); 
#  unexpected character 

에러를 검출하기 위해 반환 값이 NULL 것에 의존하는 것은 안전하지 않습니다. 예를 들어, JSON 문자열에 "null" 이외의 문자열이 포함되어 있으면 json_decode() 는 오류가 발생하지 않더라도 null 을 반환합니다.

JSON 문자열 인코딩

json_encode 함수는 PHP 배열 (또는 PHP 5.4부터 JsonSerializable 인터페이스를 구현하는 객체)을 JSON 인코딩 문자열로 변환합니다. 성공하면 JSON으로 인코딩 된 문자열을 반환하고 실패하면 FALSE를 반환합니다.

$array = [
    'name' => 'Jeff',
    'age' => 20,
    'active' => true,
    'colors' => ['red', 'blue'],
    'values' => [0=>'foo', 3=>'bar'],
];

인코딩 중에 PHP 데이터 유형 인 string, integer 및 boolean은 해당 JSON 형식으로 변환됩니다. 연관 배열은 JSON 객체로 인코딩되며, 기본 인수로 호출하면 인덱싱 된 배열은 JSON 배열로 인코딩됩니다. (배열 키가 0부터 시작하는 연속적인 숫자 시퀀스가 ​​아니라면 배열은 JSON 객체로 인코딩됩니다.)

echo json_encode($array);

산출:

{"name":"Jeff","age":20,"active":true,"colors":["red","blue"],"values":{"0":"foo","3":"bar"}}

인수

PHP 5.3부터, json_encode 대한 두 번째 인수는 다음 중 하나 이상이 될 수있는 비트 마스크입니다.

어떤 비트 마스크와 마찬가지로 이진 OR 연산자 | .

PHP 5.x 5.3

JSON_FORCE_OBJECT

배열 대신 객체 생성을 강제 실행합니다.

$array = ['Joel', 23, true, ['red', 'blue']];
echo json_encode($array);
echo json_encode($array, JSON_FORCE_OBJECT);

산출:

["Joel",23,true,["red","blue"]]
{"0":"Joel","1":23,"2":true,"3":{"0":"red","1":"blue"}}

JSON_HEX_TAG , JSON_HEX_AMP , JSON_HEX_APOS , JSON_HEX_QUOT

인코딩 중에 다음과 같은 변환을 보장합니다.

일정한 입력 산출
JSON_HEX_TAG < \u003C
JSON_HEX_TAG > \u003E
JSON_HEX_AMP & \u0026
JSON_HEX_APOS ' \u0027
JSON_HEX_QUOT " \u0022
$array = ["tag"=>"<>", "amp"=>"&", "apos"=>"'", "quot"=>"\""];
echo json_encode($array);
echo json_encode($array, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);

산출:

{"tag":"<>","amp":"&","apos":"'","quot":"\""}
{"tag":"\u003C\u003E","amp":"\u0026","apos":"\u0027","quot":"\u0022"}
PHP 5.x 5.3

JSON_NUMERIC_CHECK

숫자 문자열이 정수로 변환되도록합니다.

$array = ['23452', 23452];
echo json_encode($array);
echo json_encode($array, JSON_NUMERIC_CHECK);

산출:

["23452",23452]    
[23452,23452]
PHP 5.x 5.4

JSON_PRETTY_PRINT

JSON을 쉽게 읽을 수있게합니다.

$array = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
echo json_encode($array);
echo json_encode($array, JSON_PRETTY_PRINT);

산출:

{"a":1,"b":2,"c":3,"d":4}
{
    "a": 1,
    "b": 2,
    "c": 3,
    "d": 4
}

JSON_UNESCAPED_SLASHES

이스케이프 / 슬래시를 출력에 포함합니다.

$array = ['filename' => 'example.txt', 'path' => '/full/path/to/file/'];
echo json_encode($array);
echo json_encode($array, JSON_UNESCAPED_SLASHES);

산출:

{"filename":"example.txt","path":"\/full\/path\/to\/file"}
{"filename":"example.txt","path":"/full/path/to/file"}

JSON_UNESCAPED_UNICODE

출력에 \u 자로 인코딩 된 문자열 대신 UTF8로 인코딩 된 문자가 포함됩니다.

$blues = ["english"=>"blue", "norwegian"=>"blå", "german"=>"blau"];
echo json_encode($blues);
echo json_encode($blues, JSON_UNESCAPED_UNICODE);

산출:

{"english":"blue","norwegian":"bl\u00e5","german":"blau"}
{"english":"blue","norwegian":"blå","german":"blau"}
PHP 5.x 5.5

JSON_PARTIAL_OUTPUT_ON_ERROR

인코딩 할 수없는 값이 있으면 인코딩을 계속할 수 있습니다.

$fp = fopen("foo.txt", "r");
$array = ["file"=>$fp, "name"=>"foo.txt"];
echo json_encode($array); // no output
echo json_encode($array, JSON_PARTIAL_OUTPUT_ON_ERROR);

산출:

{"file":null,"name":"foo.txt"}
PHP 5.x 5.6

JSON_PRESERVE_ZERO_FRACTION

float가 항상 float으로 인코딩되도록합니다.

$array = [5.0, 5.5];
echo json_encode($array);
echo json_encode($array, JSON_PRESERVE_ZERO_FRACTION);

산출:

[5,5.5]
[5.0,5.5]
PHP 7.x 7.1

JSON_UNESCAPED_LINE_TERMINATORS

JSON_UNESCAPED_UNICODE 와 함께 사용하면 이전 PHP 버전의 동작으로 JSON_UNESCAPED_UNICODE U + 2028 LINE SEPARATOR 및 U + 2029 PARAGRAPH SEPARATOR 문자를 이스케이프 처리 하지 않습니다 . JSON에서 유효하지만이 문자는 JavaScript에서 유효하지 않으므로 버전 7.1에서 JSON_UNESCAPED_UNICODE 의 기본 동작이 변경되었습니다.

$array = ["line"=>"\xe2\x80\xa8", "paragraph"=>"\xe2\x80\xa9"];
echo json_encode($array, JSON_UNESCAPED_UNICODE);
echo json_encode($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS);

산출:

{"line":"\u2028","paragraph":"\u2029"}
{"line":"
","paragraph":"
"}

JSON 오류 디버깅

json_encode 또는 json_decode 가 제공된 문자열을 구문 분석하지 못하면 false 를 반환합니다. 이 경우 PHP 자체에서 오류나 경고를 발생시키지 않습니다. 사용자가 json_last_error ()json_last_error_msg () 함수를 사용하여 오류가 발생했는지 확인하고 응용 프로그램에서 이에 따라 행동해야합니다 (디버그하고 오류 메시지를 표시합니다. , 등).

다음 예제는 JSON으로 작업 할 때 발생하는 일반적인 오류를 보여줍니다. 예를 들어 잘못된 UTF-8로 인코딩 된 문자열이 전달되어 JSON 문자열을 디코딩 / 인코딩 하지 못했습니다 .

// An incorrectly formed JSON string
$jsonString = json_encode("{'Bad JSON':\xB1\x31}");

if (json_last_error() != JSON_ERROR_NONE) {
    printf("JSON Error: %s", json_last_error_msg());
}

#> JSON Error: Malformed UTF-8 characters, possibly incorrectly encoded

json_last_error_msg

json_last_error_msg() 는 문자열을 인 코드 / 디코드 할 때 발생한 마지막 오류에 대한 인간이 읽을 수있는 메시지를 반환합니다.

  • 이 함수는 오류가 발생하지 않았더라도 항상 문자열을 반환합니다 .
    기본 비 오류 문자열은 No Error
  • 다른 (알 수없는) 오류가 발생하면 false 를 반환합니다.
  • 이 루프를 사용할 때는 조심하십시오. json_last_error_msg 는 각 반복에서 재정의됩니다.

이 함수는 컨트롤 문에서 테스트 하지 않고 표시 할 메시지를 가져 오는 데만 사용해야합니다.

// Don't do this:
if (json_last_error_msg()){} // always true (it's a string)
if (json_last_error_msg() != "No Error"){} // Bad practice

// Do this: (test the integer against one of the pre-defined constants)
if (json_last_error() != JSON_ERROR_NONE) {
    // Use json_last_error_msg to display the message only, (not test against it)
    printf("JSON Error: %s", json_last_error_msg());
}

이 함수는 PHP 5.5 이전에는 존재하지 않습니다. 다음은 polyfill 구현입니다.

if (!function_exists('json_last_error_msg')) {
    function json_last_error_msg() {
        static $ERRORS = array(
            JSON_ERROR_NONE => 'No error',
            JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
            JSON_ERROR_STATE_MISMATCH => 'State mismatch (invalid or malformed JSON)',
            JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
            JSON_ERROR_SYNTAX => 'Syntax error',
            JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
        );

        $error = json_last_error();
        return isset($ERRORS[$error]) ? $ERRORS[$error] : 'Unknown error';
    }
}

json_last_error

json_last_error() 는 PHP가 제공하는 미리 정의 된 상수 중 하나에 매핑 된 정수를 반환합니다.

일정한 의미
JSON_ERROR_NONE 오류가 발생하지 않았습니다.
JSON_ERROR_DEPTH 최대 스택 깊이를 초과했습니다.
JSON_ERROR_STATE_MISMATCH 잘못되었거나 형식이 잘못된 JSON
JSON_ERROR_CTRL_CHAR 제어 문자 오류, 가능하지 않게 잘못 인코딩 됨
JSON_ERROR_SYNTAX 구문 오류 (PHP 5.3.3 이후)
JSON_ERROR_UTF8 잘못된 형식으로 인코딩 된 잘못된 형식의 UTF-8 문자 (PHP 5.5.0 이후)
JSON_ERROR_RECURSION 인코딩 할 값에서 하나 이상의 순환 참조
JSON_ERROR_INF_OR_NAN 인코딩 할 값에 하나 이상의 NAN 또는 INF 값
JSON_ERROR_UNSUPPORTED_TYPE 인코딩 할 수없는 유형의 값이 제공되었습니다.

개체에서 JsonSerializable 사용

PHP 5.x 5.4

REST API를 빌드 할 때, 클라이언트 어플리케이션에 전달할 오브젝트의 정보를 줄여야 할 수도 있습니다. 이를 위해이 예제는 JsonSerialiazble 인터페이스를 사용하는 방법을 보여줍니다.

이 예에서 클래스 User 실제로 hypotetical ORM의 DB 모델 객체를 확장합니다.

class User extends Model implements JsonSerializable {
    public $id;
    public $name;
    public $surname;
    public $username;
    public $password;
    public $email;
    public $date_created;
    public $date_edit;
    public $role;
    public $status;

    public function jsonSerialize() {
        return [
            'name' => $this->name,
            'surname' => $this->surname,
            'username' => $this->username
        ];
    }
}

jsonSerialize() 메소드를 제공하여 클래스에 JsonSerializable 구현을 추가하십시오.

public function jsonSerialize()

이제 응용 프로그램 컨트롤러 나 스크립트에서 json_encode() 객체 User를 전달할 때 전체 객체 대신 jsonSerialize() 메서드의 리턴 된 json 인코딩 된 배열을 jsonSerialize() 됩니다.

json_encode($User);

돌아올 것입니다 :

{"name":"John", "surname":"Doe", "username" : "TestJson"}

속성 값 예제.

이렇게하면 RESTful 끝점에서 반환되는 데이터 양이 줄어들고 json 표현에서 객체 속성을 제외 할 수 있습니다.


json_encode() 개인 및 보호 된 속성 사용

JsonSerializable을 사용하지 않으려면 private 또는 protected 속성을 사용하여 json_encode() 출력에서 클래스 정보를 숨길 수 있습니다. 그런 다음 클래스는 \ JsonSerializable을 구현할 필요가 없습니다.

json_encode () 함수는 클래스의 public 속성을 JSON으로 인코딩합니다.

<?php

class User {
    // private properties only within this class
    private $id;
    private $date_created;
    private $date_edit;

    // properties used in extended classes
    protected $password;
    protected $email;
    protected $role;
    protected $status;

    // share these properties with the end user        
    public $name;
    public $surname;
    public $username;

    // jsonSerialize() not needed here
}        

$theUser = new User();

var_dump(json_encode($theUser));

산출:

string(44) "{"name":null,"surname":null,"username":null}"

헤더 json과 반환 된 응답

콘텐츠 유형이 JSON 인 헤더 추가 :

<?php
 $result = array('menu1' => 'home', 'menu2' => 'code php', 'menu3' => 'about');

//return the json response :
header('Content-Type: application/json');  // <-- header declaration
echo json_encode($result, true);    // <--- encode
exit();

헤더가 있으므로 앱에서 반환 된 데이터와이를 처리하는 방법을 앱에서 감지 할 수 있습니다.
그 참고 : 콘텐츠 헤더가 반환 된 데이터의 유형에 대한 단지 정보입니다.

UTF-8을 사용하는 경우 다음을 사용할 수 있습니다.

header("Content-Type: application/json;charset=utf-8");

예제 jQuery :

$.ajax({
        url:'url_your_page_php_that_return_json'        
    }).done(function(data){
        console.table('json ',data);
        console.log('Menu1 : ', data.menu1);
    });


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow