如何使用 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()
,事情就会开始变得棘手。见:
如何排序
请参阅: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 中提取和访问数据?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 PHP [Json results from open alpr] 中读取这种类型的 JSON 文件?
SQL JSON PATH 如何在从较大的 json 集中提取后按索引访问 json 数组