如何使用PHP从JSON中提取数据?

How do I extract data from JSON with PHP?

This is intended to be a general reference question and answer covering many of the never-ending"How do I access data in my JSON?" questions. It is here to handle the broad basics of decoding JSON in PHP and accessing the results.

我有JSON:

1
2
3
4
5
6
7
8
9
{
   "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中解码它。

1
 $data = json_decode($json);

在那里你可能会发现:

  • 标量:字符串,整数,浮点数和布尔值
  • nulls(它自己的特殊类型)
  • 复合类型:对象和数组。
  • 这些是可以用JSON编码的东西。或者更准确地说,这些是可以用JSON编码的PHP版本。

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

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

    访问对象属性

    您可以像访问任何其他对象的公共非静态属性一样访问其中一个对象的属性,例如$object->property

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $json = '
    {
       "type":"donut",
       "name":"Cake"
    }'
    ;

    $yummy = json_decode($json);

    echo $yummy->type; //donut

    访问数组元素

    您可以像访问任何其他数组一样访问其中一个数组的元素,例如$array[0]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $json = '
    [
       "Glazed",
       "Chocolate with Sprinkles",
       "Maple"
    ]'
    ;

    $toppings = json_decode($json);

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

    foreach迭代它。

    1
    2
    3
    4
    foreach ($toppings as $topping) {
        echo $topping,"
    "
    ;
    }

    Glazed
    Chocolate with Sprinkles
    Maple

    Ok.

    或者搞乱任何一个数以亿计的内置数组函数。

    访问嵌套项

    对象的属性和数组的元素可能是更多的对象和/或数组 - 您可以像往常一样继续访问其属性和成员,例如$object->array[0]->etc

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $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()

    当你这样做时,你将获得关联数组而不是对象 - 带有键的字符串的数组。您可以像往常一样访问其元素,例如<5233>。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $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)语法迭代键和值,例如

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $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;
    }

    打印

    The value of key 'foo' is 'foo value'
    The value of key 'bar' is 'bar value'
    The value of key 'baz' is 'baz value'

    Ok.

    不知道数据的结构

    阅读文档,了解您从中获取JSON的任何内容。

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $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);

    并检查输出:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    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()点击它:

    1
    print_r($yummy->toppings[0]);
    1
    2
    3
    4
    5
    stdClass Object
    (
        [id] => 5002
        [type] => Glazed
    )

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

    将问题分解成更容易缠绕的部分。

    json_decode()返回null

    发生这种情况是因为:

  • JSON完全由null组成。
  • JSON无效 - 检查json_last_error_msg的结果或通过类似JSONLint的内容。
  • 它包含嵌套超过512级深度的元素。可以通过将整数作为第三个参数传递给json_decode()来覆盖此默认最大深度。
  • 如果你需要改变最大深度,你可能正在解决错误的问题。找出你为什么得到如此深层嵌套的数据(例如,你正在查询生成JSON的服务有一个错误)并且不会发生这种情况。

    对象属性名称包含特殊字符

    有时,您将拥有一个对象属性名称,其中包含连字符-或符号@,不能在文字标识符中使用。相反,您可以在花括号内使用字符串文字来解决它。

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

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

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

    有人把JSON放在你的JSON中

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $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中对数组和数据进行排序的所有基本方法。

    好。


    您可以使用json_decode()将json字符串转换为PHP对象/数组。

    例如。

    输入:

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

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

    输出:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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)
    }

    几点要记住:

    • json_decode要求字符串是有效的json否则它将返回NULL
    • 如果解码失败,json_last_error()可用于确定错误的确切性质。
    • 确保传入utf8内容,否则json_decode可能会出错,只返回NULL值。


    我们可以使用php中的json_decode函数将json字符串解码为数组

    1)json_decode($ json_string)//它返回对象

    2)json_decode($ json_string,true)//它返回数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $json_string = '{
       "type":"donut",
       "name":"Cake",
       "toppings": [
            {"id":"5002","type":"Glazed" },
            {"id":"5006","type":"Chocolate with Sprinkles" },
            {"id":"5004","type":"Maple" }
        ]
    }'
    ;
    $array = json_decode($json_string,true);

    echo $array['type']; //it gives donut

    https://paiza.io/projects/X1QjjBkA8mDo6oVh-J_63w

    检查下面的代码,将json转换为PHP中的数组,
    如果JSON是正确的那么json_decode()运行良好,并将返回一个数组,
    但如果格式错误的JSON,那么它将返回NULL

    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    function jsonDecode1($json){
        $arr = json_decode($json, true);
        return $arr;
    }

    // In case of malformed JSON, it will return NULL
    var_dump( jsonDecode1($json) );

    如果格式错误的JSON,并且您只期望数组,则可以使用此函数,

    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    function jsonDecode2($json){
        $arr = (array) json_decode($json, true);
        return $arr;
    }

    // In case of malformed JSON, it will return an empty array()
    var_dump( jsonDecode2($json) );

    如果格式错误的JSON,并且您想要停止代码执行,那么您可以使用此功能,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?php
    function jsonDecode3($json){
        $arr = (array) json_decode($json, true);

        if(empty(json_last_error())){
            return $arr;
        }
        else{
            throw new ErrorException( json_last_error_msg() );
        }
    }

    // In case of malformed JSON, Fatal error will be generated
    var_dump( jsonDecode3($json) );

    你可以使用任何功能取决于你的要求,


    我写了一个名为json的包(GitHub,Packagist)。如果你想防止使用json_*函数的开销,你应该尝试一下。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    use MAChitgarha\Component\JSON;

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

    // Create an instance
    $json = new JSON($jsonStr);

    // Get a nested element using dots
    $json->get("toppings.1.type"); // Chocolate with Sprinkles
    $json["toppings.1.type"]; // Chocolate with Sprinkles

    // Iterate over an element
    foreach ($json->iterate("toppings") as $item)
        echo"{$item->id}: {$item->type}", PHP_EOL;

    // Change an element
    $json->set("toppings.3", [
       "id" =>"5000",
       "type" =>"Unknown"
    ]);

    // Get data as JSON string, array or object, respectively
    $json->getDataAsJson();
    $json->getDataAsArray();
    $json->getDataAsObject();

    请参阅wiki或快速教程以熟悉它。

    此外,如果您想要读取JSON文件并提取其数据(因为您似乎正在尝试执行此操作),请参阅我编写的JSONFile包。