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


214

这旨在作为一般参考问题和答案,涵盖许多永无止境的“如何访问JSON中的数据?” 问题。它在这里处理在PHP中解码JSON和访问结果的广泛基础知识。

我有JSON:

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

如何在PHP中对此进行解码并访问结果数据?



请问我知道为什么这个问题即使是9个或以下标记为stackoverflow.com/questions/4343596/parsing-json-file-with-php重复项的用户也不能视为重复问题?M
我是最愚蠢的人

@IamtheMostStupidPerson我将尽力解释,即使您的用户名让我怀疑您是否会得到它;)。该问题以“规范”方式提出,并给出了答案。因此,与其他问题相比,它是重复目标的更好接收者。
费利克斯·加侬-格雷尼尔

Answers:


428

介绍

首先,您有一个字符串。JSON不是数组,对象或数据结构。JSON是一种基于文本的序列化格式,因此是花哨的字符串,但仍然只是字符串。使用解码PHP json_decode()

 $data = json_decode($json);

在其中您可能会发现:

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

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

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


访问对象属性

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

$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]->etc

$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

发生这种情况的原因是:

  1. JSON完全由组成null
  2. JSON无效-检查结果json_last_error_msg或将其放入JSONLint之类的内容
  3. 它包含嵌套超过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中对数组和数据进行排序的所有基本方法


刚刚迷失了这个答案,发现array.include-once.org的链接已损坏。
杰夫

@杰夫谢谢。对此感到羞耻。我已删除链接。
user3942918

是的,考虑到链接的名称以及您如何描述它,这听起来真是令人讨厌。
杰夫

该解决方案唯一缺少的是如何从另一个json文件提取数据。我建议,这solutuon:stackoverflow.com/questions/19758954/...
依禅塔瓦

这很棒。谢谢。
David Kariuki

17

您可以使用json_decode()将json字符串转换为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)
}

要记住的几点:

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

好吧,尽管如此,他们可能不喜欢它的简单性。您随时可以投票;)
Mohd Abdul Mujib

1
可能更可能的原因是它已经得到了答复,并且@MohdAbdulMujib似乎已经受到了一些免费代表的追捧
Isaac

3
@Isaac有些人可能只想开始使用该功能时可能并不十分乐于阅读整本手册。否则,最好阅读官方文档。SO的全部重点是提供答案的简单性。恕我直言
Mohd Abdul Mujib

3
// Using json as php array 

$json = '[{"user_id":"1","user_name":"Sayeed Amin","time":"2019-11-06 13:21:26"}]';

//or use from file
//$json = file_get_contents('results.json');

$someArray = json_decode($json, true);

foreach ($someArray as $key => $value) {
    echo $value["user_id"] . ", " . $value["user_name"] . ", " . $value["time"] . "<br>";
}

1

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

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

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

$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


-1

我已经写了一个名为JSONGitHubPackagist)的包。如果要防止使用的开销json_*函数的,则应尝试一下。

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包,我也已经编写了它。


-2

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

检查以下用于将json转换为array的代码PHP,如果JSON正确,则json_decode()工作正常,并将返回一个数组;但是,如果JSON格式不正确,则它将返回NULL

<?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格式错误,并且您只希望使用数组,则可以使用此函数,

<?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格式错误,并且您想停止执行代码,则可以使用此功能,

<?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) );

您可以根据需要使用任何功能,

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.