这是一个一般的参考问题和回答,涵盖了许多永无止境的“我如何访问JSON中的数据?”问题。这里将处理在PHP中解码JSON和访问结果的基本知识。

我有JSON:

{
    "type": "donut",
    "name": "Cake",
    "toppings": [
        { "id": "5002", "type": "Glazed" },
        { "id": "5006", "type": "Chocolate with Sprinkles" },
        { "id": "5004", "type": "Maple" }
    ]
}

我如何解码这在PHP和访问结果数据?


介绍

首先你有一根弦。JSON不是数组、对象或数据结构。JSON是一种基于文本的序列化格式——一个奇特的字符串,但仍然只是一个字符串。通过使用json_decode()在PHP中解码它。

 $data = json_decode($json);

你可能会发现:

标量:字符串、int型、浮点型和bool型 null(它自己的一种特殊类型) 复合类型:对象和数组。

这些是可以用JSON编码的东西。或者更准确地说,这些是可以用JSON编码的东西的PHP版本。

他们没有什么特别的。它们不是“JSON对象”或“JSON数组”。您已经解码了JSON—现在您拥有了基本的日常PHP类型。

对象将是stdClass的实例,stdClass是一个内置类,它只是一个通用的东西,在这里不重要。


访问对象属性

访问其中一个对象的属性的方式与访问任何其他对象的公共非静态属性的方式相同,例如$object->属性。

$json = '
{
    "type": "donut",
    "name": "Cake"
}';

$yummy = json_decode($json);

echo $yummy->type; //donut

访问数组元素

访问其中一个数组的元素与访问其他数组(例如$array[0])的方式相同。

$json = '
[
    "Glazed",
    "Chocolate with Sprinkles",
    "Maple"
]';

$toppings = json_decode($json);

echo $toppings[1]; //Chocolate with Sprinkles

用foreach迭代它。

foreach ($toppings as $topping) {
    echo $topping, "\n";
}

上釉 巧克力碎 枫木

或者在无数内置数组函数中瞎折腾。


访问嵌套项

对象的属性和数组的元素可以是更多的对象和/或数组——你可以像往常一样简单地继续访问它们的属性和成员,例如$object->array[0]->等等。

$json = '
{
    "type": "donut",
    "name": "Cake",
    "toppings": [
        { "id": "5002", "type": "Glazed" },
        { "id": "5006", "type": "Chocolate with Sprinkles" },
        { "id": "5004", "type": "Maple" }
    ]
}';

$yummy = json_decode($json);

echo $yummy->toppings[2]->id; //5004

将true作为第二个参数传递给json_decode()

当你这样做的时候,你得到的不是对象,而是关联数组——用字符串作为键的数组。同样,您可以像往常一样访问其中的元素,例如$array['key']。

$json = '
{
    "type": "donut",
    "name": "Cake",
    "toppings": [
        { "id": "5002", "type": "Glazed" },
        { "id": "5006", "type": "Chocolate with Sprinkles" },
        { "id": "5004", "type": "Maple" }
    ]
}';

$yummy = json_decode($json, true);

echo $yummy['toppings'][2]['type']; //Maple

访问关联数组项

当将JSON对象解码为关联PHP数组时,您可以使用foreach (array_expression as $key => $value)语法迭代键和值

$json = '
{
    "foo": "foo value",
    "bar": "bar value",
    "baz": "baz value"
}';

$assoc = json_decode($json, true);
foreach ($assoc as $key => $value) {
    echo "The value of key '$key' is '$value'", PHP_EOL;
}

打印

键foo的值是foo value 键'bar'的值是'bar value' 键" baz "的值是" baz value "


不知道数据是如何结构的

阅读文档,了解JSON的来源。

看看JSON——在这里你看到花括号{}期望一个对象,在这里你看到方括号[]期望一个数组。

使用print_r()命中解码后的数据:

$json = '
{
    "type": "donut",
    "name": "Cake",
    "toppings": [
        { "id": "5002", "type": "Glazed" },
        { "id": "5006", "type": "Chocolate with Sprinkles" },
        { "id": "5004", "type": "Maple" }
    ]
}';

$yummy = json_decode($json);

print_r($yummy);

并检查输出:

stdClass Object
(
    [type] => donut
    [name] => Cake
    [toppings] => Array
        (
            [0] => stdClass Object
                (
                    [id] => 5002
                    [type] => Glazed
                )

            [1] => stdClass Object
                (
                    [id] => 5006
                    [type] => Chocolate with Sprinkles
                )

            [2] => stdClass Object
                (
                    [id] => 5004
                    [type] => Maple
                )

        )

)

它会告诉你在哪里有对象,在哪里有数组,以及它们成员的名称和值。

如果你只能在迷失之前深入到这里,那么就用print_r():

print_r($yummy->toppings[0]);
stdClass Object
(
    [id] => 5002
    [type] => Glazed
)

在这个方便的交互式JSON资源管理器中查看它。

把问题分解成更容易理解的小块。


Json_decode()返回null

发生这种情况是因为:

JSON完全由null组成。 JSON是无效的-检查json_last_error_msg的结果或将其放入类似JSONLint的东西中。 它包含嵌套深度超过512层的元素。可以通过将一个整数作为第三个参数传递给json_decode()来覆盖这个默认的最大深度。

如果你需要改变最大深度,你可能解决了错误的问题。弄清楚为什么你会得到如此深嵌套的数据(例如,你正在查询的生成JSON的服务有一个错误),并让这种情况不会发生。


对象属性名包含一个特殊字符

有时你会有一个对象属性名,其中包含像连字符-或@这样不能用于字面标识符的东西。相反,您可以使用花括号内的字符串文字来解决它。

$json = '{"@attributes":{"answer":42}}';
$thing = json_decode($json);

echo $thing->{'@attributes'}->answer; //42

如果你有一个整数作为属性,请参阅:如何访问对象属性的名称,如整数?作为参考。


有人把JSON放到了你的JSON中

这很荒谬,但它确实发生了——JSON中有编码为字符串的JSON。解码,像往常一样访问字符串,解码,最终得到你需要的东西。

$json = '
{
    "type": "donut",
    "name": "Cake",
    "toppings": "[{ \"type\": \"Glazed\" }, { \"type\": \"Maple\" }]"
}';

$yummy = json_decode($json);
$toppings = json_decode($yummy->toppings);

echo $toppings[0]->type; //Glazed

数据不适合内存

如果JSON太大,json_decode()无法立即处理,那么事情就会变得棘手。看到的:

在PHP中处理大型JSON文件 如何正确地迭代通过一个大json文件


如何排序

参见:参考:PHP中排序数组和数据的所有基本方法。