解码 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
,即使没有发生错误。