json_decode

(PHP 5 >= 5.2.0, PHP 7, PHP 8, PECL json >= 1.2.0)

json_decode解码 JSON 字符串

描述

json_decode(
    字符串 $json,
    ?布尔值 $associative = null,
    整数 $depth = 512,
    整数 $flags = 0
): 混合

接受一个 JSON 编码的字符串,并将其转换为 PHP 值。

参数

json

要解码的 json 字符串

此函数仅适用于 UTF-8 编码的字符串。

注意:

PHP 实现了一个 JSON 的超集,如原始的 » RFC 7159 中所述。

associative

当为 true 时,JSON 对象将作为关联的 数组 返回;当为 false 时,JSON 对象将作为 对象 返回。当为 null 时,JSON 对象将作为关联的 数组对象 返回,具体取决于 flags 中是否设置了 JSON_OBJECT_AS_ARRAY

depth

正在解码的结构的最大嵌套深度。该值必须大于 0,小于或等于 2147483647

flags

JSON_BIGINT_AS_STRINGJSON_INVALID_UTF8_IGNOREJSON_INVALID_UTF8_SUBSTITUTEJSON_OBJECT_AS_ARRAYJSON_THROW_ON_ERROR 的位掩码。这些常量的行为在 JSON 常量 页面上进行了描述。

返回值

json 中编码的值作为适当的 PHP 类型返回。未引用的值 truefalsenull 分别作为 truefalsenull 返回。如果无法解码 json 或编码的数据深度超过嵌套限制,则返回 null

错误/异常

如果 depth 超出允许范围,则从 PHP 8.0.0 开始将抛出 ValueError,而之前会引发级别为 E_WARNING 的错误。

变更日志

版本 描述
7.3.0 添加了 JSON_THROW_ON_ERROR flags
7.2.0 associative 现在可以为空。
7.2.0 添加了 JSON_INVALID_UTF8_IGNOREJSON_INVALID_UTF8_SUBSTITUTE flags
7.1.0 空 JSON 键 ("") 可以编码为空对象属性,而不是使用值为 _empty_ 的键。

示例

示例 #1 json_decode() 示例

<?php
$json
= '{"a":1,"b":2,"c":3,"d":4,"e":5}';

var_dump(json_decode($json));
var_dump(json_decode($json, true));

?>

上面的示例将输出

object(stdClass)#1 (5) {
    ["a"] => int(1)
    ["b"] => int(2)
    ["c"] => int(3)
    ["d"] => int(4)
    ["e"] => int(5)
}

array(5) {
    ["a"] => int(1)
    ["b"] => int(2)
    ["c"] => int(3)
    ["d"] => int(4)
    ["e"] => int(5)
}

示例 #2 访问无效的对象属性

可以通过将元素名称封装在花括号和撇号中来访问对象中包含 PHP 命名约定不允许的字符(例如连字符)的元素。

<?php

$json
= '{"foo-bar": 12345}';

$obj = json_decode($json);
print
$obj->{'foo-bar'}; // 12345

?>

示例 #3 使用 json_decode() 的常见错误

<?php

// 以下字符串是有效的 JavaScript,但不是有效的 JSON

// 名称和值必须用双引号括起来
// 单引号无效
$bad_json = "{ 'bar': 'baz' }";
json_decode($bad_json); // null

// 名称必须用双引号括起来
$bad_json = '{ bar: "baz" }';
json_decode($bad_json); // null

// 不允许使用尾随逗号
$bad_json = '{ bar: "baz", }';
json_decode($bad_json); // null

?>

示例 #4 depth 错误

<?php
// 编码一些数据,最大深度为 4(数组 -> 数组 -> 数组 -> 字符串)
$json = json_encode(
array(
1 => array(
'English' => array(
'One',
'January'
),
'French' => array(
'Une',
'Janvier'
)
)
)
);

// 显示不同深度的错误。
var_dump(json_decode($json, true, 4));
echo
'Last error: ', json_last_error_msg(), PHP_EOL, PHP_EOL;

var_dump(json_decode($json, true, 3));
echo
'Last error: ', json_last_error_msg(), PHP_EOL, PHP_EOL;
?>

上面的示例将输出

array(1) {
  [1]=>
  array(2) {
    ["English"]=>
    array(2) {
      [0]=>
      string(3) "One"
      [1]=>
      string(7) "January"
    }
    ["French"]=>
    array(2) {
      [0]=>
      string(3) "Une"
      [1]=>
      string(7) "Janvier"
    }
  }
}
Last error: No error

NULL
Last error: Maximum stack depth exceeded

示例 #5 json_decode() 的大整数

<?php
$json
= '{"number": 12345678901234567890}';

var_dump(json_decode($json));
var_dump(json_decode($json, false, 512, JSON_BIGINT_AS_STRING));

?>

上面的示例将输出

object(stdClass)#1 (1) {
  ["number"]=>
  float(1.2345678901235E+19)
}
object(stdClass)#1 (1) {
  ["number"]=>
  string(20) "12345678901234567890"
}

注意

注意:

JSON 规范不是 JavaScript,而是 JavaScript 的一个子集。

注意:

如果解码失败,可以使用 json_last_error() 来确定错误的确切性质。

参见

添加笔记

用户贡献笔记 4 笔记

Lennart Hengstmengel
2 年前
JSON 可以使用 $associative = true 选项解码为 PHP 数组。注意,PHP 中的关联数组在转换为/从 JSON 转换时可能是“列表”或“对象”,具体取决于键(或键的缺失)。

您可能会认为重新编码和重新编码将始终产生相同的 JSON 字符串,但请看下面的示例

$json = '{"0": "No", "1": "Yes"}';
$array = json_decode($json, true); // 解码为关联哈希
print json_encode($array) . PHP_EOL;

这将输出与原始 JSON 字符串不同的字符串

["No","Yes"]

对象已变成数组!

类似地,没有连续从零开始的数字索引的数组将被编码为 JSON 对象而不是列表。

$array = [
'first',
'second',
'third',
];
print json_encode($array) . PHP_EOL;
// 删除第二个元素
unset($array[1]);
print json_encode($array) . PHP_EOL;

输出将是

["first","second","third"]
{"0":"first","2":"third"}

数组已变成对象!

换句话说,从 PHP 数组解码/编码并不总是对称的,或者可能并不总是返回您期望的结果!

另一方面,从/向 stdClass 对象(默认)解码/编码始终是对称的。

数组可能比对象更容易操作/转换。但尤其是在需要解码和重新编码 json 时,明智的做法是解码为对象而不是数组。

如果要强制将数组编码为 JSON 列表(所有数组键将被丢弃),请使用

json_encode(array_values($array));

如果要强制将数组编码为 JSON 对象,请使用

json_encode((object)$array);

另请参阅:https://php.net/manual/en/function.array-is-list.php
greaties at ghvernuft dot nl
1 年前
要使用 json 格式的数据加载对象
(已修复我之前评论中的错误)

<?php
function loadJSON($Obj, $json)
{
$dcod = json_decode($json);
$prop = get_object_vars ( $dcod );
foreach(
$prop as $key => $lock)
{
if(
property_exists ( $Obj , $key ))
{
if(
is_object($dcod->$key))
{
loadJSON($Obj->$key, json_encode($dcod->$key));
}
else
{
$Obj->$key = $dcod->$key;
}
}
}
return
$Obj;
}
?>

使用以下内容进行了测试

<?php
class Name
{
public
$first;
public
$last;
public function
fullname()
{
return
$this->first . " " . $this->last;
}
}
$json = '{"first":"John","last":"Smith"}';

$infull = loadJSON((new Name), $json);
echo
$infull->fullname();
cubefox at web dot NOSPAMPLEASE dot de
3 年前
警告:如“返回值”部分所述,返回值 NULL 是模棱两可的。重复一下,它可以表示三件事

* 输入字符串的值为“null”
* 解析输入数据时出错
* 编码数据比递归限制更深

要区分这些情况,可以使用 json_last_error()。
Alien426
3 年前
浏览器不会因以 BigInt(64 位)开头的整数而卡死,但会在之前的整数(53 位)卡死。当 JSON 处理函数不支持 BigInt 时,在现代浏览器中引入 BigInt 并没有太大帮助。因此我正在尝试解决这个问题。我的方法是在重新编码为字符串之前处理解码的数组
<?php
function fix_large_int(&$value)
{
if (
is_int($value) && $value > 9007199254740991)
$value = strval($value);
}
$json_str = '{"id":[1234567890123456789,12345678901234567890]}';
$json_arr = json_decode($json_str, flags: JSON_BIGINT_AS_STRING | JSON_OBJECT_AS_ARRAY);
echo(
json_encode($json_arr)); // {"id":[1234567890123456789,"12345678901234567890"]} (BigInt 已在此处转换为字符串)
array_walk_recursive($json_arr, 'fix_large_int');
echo(
json_encode($json_arr)); // {"id":["1234567890123456789","12345678901234567890"]}
?>
To Top