解码 JSON 字符串

所述 json_decode() 函数采用一个 JSON 编码的字符串的第一个参数并将其解析为一个 PHP 变量。

通常,如果 JSON 对象中的顶级项是字典,则 json_decode() 将返回 \ stdClass对象, 如果 JSON 对象是数组,则返回索引数组。对于某些标量值,它还会返回标量值或 NULL,例如简单字符串,truefalsenull。它还会在任何错误时返回 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 标准。因此,像 JSLintJSON 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"

falsenull 也出现类似的行为。

请注意,如果无法转换字符串,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,即使没有发生错误。