解碼 JSON 字串
所述 json_decode()
函式採用一個 JSON 編碼的字串的第一個引數並將其解析為一個 PHP 變數。
通常,如果 JSON 物件中的頂級項是字典,則 json_decode()
將返回 \ stdClass 的物件, 如果 JSON 物件是陣列,則返回索引陣列。對於某些標量值,它還會返回標量值或 NULL
,例如簡單字串,true
,false
和 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
。在版本 5.3 或更高版本中,可以使用第三個引數($depth
)來控制此限制,如下所述。
根據手冊:
PHP 實現了原始 »RFC 4627 中指定的 JSON 超集 - 它還將編碼和解碼標量型別和 NULL。RFC 4627 僅在巢狀在陣列或物件中時才支援這些值。雖然這個超集與更新的 »RFC 7159 (旨在取代 RFC 4627)和 »ECMA-404 中的“JSON 文字”的擴充套件定義一致,但這可能會導致與舊的 JSON 解析器的互操作性問題,這些解析器嚴格遵守 RFC 4627 編碼單個標量值。
這意味著,例如,一個簡單的字串將被視為 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 模式下) 這樣的線上檢查器會給你一個錯誤。
遞迴深度有第三個 $depth
引數(預設值為 512
),這意味著要解碼的原始物件內的巢狀物件的數量。
第四個 $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
。
$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
,即使沒有發生錯誤。