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

Posted

技术标签:

【中文标题】如何使用 PHP 从 JSON 中提取和访问数据?【英文标题】:How to extract and access data from JSON with PHP? 【发布时间】:2022-01-15 14:03:14 【问题描述】:

这是一个通用的参考问题和答案,涵盖了许多永无止境的“我如何访问我的 JSON 中的数据?” 问题。它在这里处理在 php 中解码 JSON 和访问结果的广泛基础知识。

我有 JSON:


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

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

【问题讨论】:

相关:Able to see a variable in print_r()'s output, but not sure how to access it in code,此处可以在 PHP 上下文中进行交互式 JSON 探索:array.include-once.org 请我知道为什么即使有 9 个或更少的用户标记为 ***.com/questions/4343596/parsing-json-file-with-php 的重复问题,为什么这个问题也不被视为重复问题?米 @IamtheMostStupidPerson 我会试着解释一下,即使你的用户名让我怀疑你会明白;)。以“规范”的方式提出这个问题,并写下它的答案。因此,它比其他问题更适合重复目标。 【参考方案1】:

简介

首先你有一个字符串。 JSON 不是数组、对象或数据结构。 JSON 是一种基于文本的序列化格式——所以是一个花哨的字符串,但仍然只是一个字符串。使用json_decode()在PHP中对其进行解码。

 $data = json_decode($json);

你可能会发现:

标量:strings、ints、floats 和 bools nulls(它自己的特殊类型) 复合类型:objects 和 arrays。

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

它们没有什么特别之处。它们不是“JSON 对象”或“JSON 数组”。您已解码 JSON - 您现在拥有 basic everyday PHP types。

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


访问对象属性

您访问这些对象之一的properties 的方式与访问任何其他对象的公共非静态属性的方式相同,例如$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";

釉面 洒巧克力 枫树

或与bazillion built-in array functions 中的任何一个混在一起。


访问嵌套项

对象的属性和数组的元素可能是更多的对象和/或数组 - 您可以像往常一样简单地继续访问它们的属性和成员,例如$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 object 解码为关联 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
)

去this handy interactive JSON explorer看看吧。

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


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

如果您有一个整数作为属性,请参阅:How to access object properties with names like integers? 作为参考。


有人将 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(),事情就会开始变得棘手。见:

Processing large JSON files in PHP How to properly iterate through a big json file

如何排序

请参阅:Reference: all basic ways to sort arrays and data in PHP。

【讨论】:

刚刚偶然发现这个答案,发现指向array.include-once.org的链接已损坏。 是的,考虑到链接的名称以及您对它的描述,这听起来很糟糕。 这个解决方案唯一缺乏的是如何从另一个 json 文件中提取数据。我会推荐这个解决方案:***.com/questions/19758954/… 这很漂亮,真的。我需要的关于 json 编码/解码的每一个说明,我都在这里找到了。我什至不得不将此页面添加为书签以便于参考。你真是个天才。【参考方案2】:

您可以使用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 值。

【讨论】:

可能更可能的原因是它已经得到了回答,看起来@MohdAbdulMujib 正在寻求一些免费代表 @Isaac 有些人在刚开始使用该功能时可能不太热衷于阅读整本手册。否则他们最好阅读官方文档。 SO的重点是提供答案的简单性。恕我直言 【参考方案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>";

【讨论】:

如果数据像 29MB 这样大,这是否仍然有效,请帮助。你能举个例子吗?我只需要 AFG 中当前的 covid 病例数。 covid.ourworldindata.org/data/owid-covid-data.json【参考方案4】:

我们可以使用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

【讨论】:

【参考方案5】:

考虑使用JSONPath https://packagist.org/packages/flow/jsonpath

对于如何使用它并解析 JSON 文件 避免所有建议的循环,有一个非常清楚的解释。如果您熟悉XPath for XML,您将开始喜欢这种方法。

【讨论】:

【参考方案6】:

在大多数情况下,接受的答案非常详细且正确。

我只想补充一点,我在尝试加载使用 UTF8 编码的 JSON 文本文件时遇到错误,我有一个格式正确的 JSON,但“json_decode”总是返回 NULL,这是由于 BOM mark .

为了解决这个问题,我做了这个 PHP 函数:

function load_utf8_file($filePath)

    $response = null;
    try
    
        if (file_exists($filePath)) 
            $text = file_get_contents($filePath);
            $response = preg_replace("/^\xEF\xBB\xBF/", '', $text);          
             
     catch (Exception $e) 
      echo 'ERROR: ',  $e->getMessage(), "\n";
   
   finally  
   return $response;

然后我像这样使用它来加载一个 JSON 文件并从中获取一个值:

$str = load_utf8_file('appconfig.json'); 
$json = json_decode($str, true); 
//print_r($json);
echo $json['prod']['deploy']['hostname'];

【讨论】:

【参考方案7】:

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

查看下面的代码,将PHP中的json转换为数组, 如果 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) );

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

【讨论】:

以上是关于如何使用 PHP 从 JSON 中提取和访问数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 JWTAuth JSON 数据中访问单个值

PHP:如何从字符串转储中提取 JSON 字符串

如何从 PHP [Json results from open alpr] 中读取这种类型的 JSON 文件?

SQL JSON PATH 如何在从较大的 json 集中提取后按索引访问 json 数组

我们如何从 JSON 响应中访问包含连字符的数据? [复制]

PHP从mysql中取出多组数据 如何加入数组中并转成JSON数组