수색…
소개
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 객체의 연관 배열 을 반환하려면 true
를 json_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"
false
및 null
대해서도 비슷한 문제가 발생합니다.
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 연산자 |
.
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"}
JSON_NUMERIC_CHECK
숫자 문자열이 정수로 변환되도록합니다.
$array = ['23452', 23452];
echo json_encode($array);
echo json_encode($array, JSON_NUMERIC_CHECK);
산출:
["23452",23452]
[23452,23452]
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"}
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"}
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]
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 사용
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);
});