如何使用 PHP 解析 JSON 文件? [复制]
Posted
技术标签:
【中文标题】如何使用 PHP 解析 JSON 文件? [复制]【英文标题】:How can I parse a JSON file with PHP? [duplicate] 【发布时间】:2011-05-19 14:52:27 【问题描述】:我尝试使用 php 解析 JSON 文件。但我现在卡住了。
这是我的 JSON 文件的内容:
"John":
"status":"Wait"
,
"Jennifer":
"status":"Active"
,
"James":
"status":"Active",
"age":56,
"count":10,
"progress":0.0029857,
"bad":0
这是我迄今为止尝试过的:
<?php
$string = file_get_contents("/home/michael/test.json");
$json_a = json_decode($string, true);
echo $json_a['John'][status];
echo $json_a['Jennifer'][status];
但是因为我事先不知道名称(如'John'
、'Jennifer'
)和所有可用的键和值(如'age'
、'count'
),我想我需要创建一些foreach 循环。
我会很感激这个例子。
【问题讨论】:
你在正确的轨道上。查找 foreach 的语法(您应该获得键和值)。不要放弃! @Stefan Mai:foreach($variable as $key => $val)
应该是你想要的 :-)
@JamWaffles 哈哈,谢谢。我希望OP可以在查找它时获得一些经验。赞成,因为这确实是他/她所需要的。
旁注:我建议您配置您的 PHP 设置以显示所有类型的错误消息,包括 notices
你能否详细说明你试图从“解析”JSON 中得到什么:即你试图用你的代码完成什么任务(例如:“输出所有状态”、“查找名称” where status is xyz", "find all information for xyz")?
【参考方案1】:
要遍历多维数组,可以使用RecursiveArrayIterator
$jsonIterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator(json_decode($json, TRUE)),
RecursiveIteratorIterator::SELF_FIRST);
foreach ($jsonIterator as $key => $val)
if(is_array($val))
echo "$key:\n";
else
echo "$key => $val\n";
输出:
John:
status => Wait
Jennifer:
status => Active
James:
status => Active
age => 56
count => 10
progress => 0.0029857
bad => 0
run on codepad
【讨论】:
这种方法与旧的 foreach 相比有什么特别的优势吗? @Álvaro 显然。使用 foreach 您只能递归一级深度。使用上述方法,您可以递归多级数组。此外,整个事情都封装在 OOP 中,因此您可以更好地重用,并且可以轻松地在 UnitTests 中模拟它,此外,您可以将迭代器与其他迭代器堆叠起来,做不同的事情,比如限制、缓存、过滤等......除了任何您可能想要创建的自定义迭代器。 好吧,我没有考虑到嵌套级别是可变的。在这种情况下,这比递归函数更干净。 这种风格解析,但是,留下一些歧义。例如,'John':'status':'waiting', 'Mary':'status','nested', 'Suzy':'status:'waiting'
与 'John':'status':'waiting', 'Mary':'status','nested', 'Suzy':'status:'waiting'
无法区分。 Mary
是 John
的结构子代丢失了。
@Jesse php.net/manual/en/class.recursiveiteratoriterator.php 将允许您检测深度。【参考方案2】:
我不敢相信这么多人在没有正确阅读 JSON 的情况下发布答案。
如果你 foreach 单独迭代 $json_a
,你有一个对象的对象。即使你传入true
作为第二个参数,你也有一个二维数组。如果您正在循环遍历第一个维度,则不能像这样回显第二个维度。所以这是错误的:
foreach ($json_a as $k => $v)
echo $k, ' : ', $v;
要回显每个人的状态,试试这个:
<?php
$string = file_get_contents("/home/michael/test.json");
if ($string === false)
// deal with error...
$json_a = json_decode($string, true);
if ($json_a === null)
// deal with error...
foreach ($json_a as $person_name => $person_a)
echo $person_a['status'];
?>
【讨论】:
如果php和json文件在同一个目录下,我们可以用file_get_contents("test.json");
读取json(不用放路径)。
@Chetabahana 这实际上是不正确的。如果您使用像test.json
这样的相对路径,则路径是相对于当前目录进行评估的,不一定是 PHP 脚本所在的位置。在 bash 上,您可以通过键入 pwd
来发现当前目录。
@Flimm 如果 PHP 和 JSON 和执行发生在同一目录下,则无需指定 JSON 文件的绝对路径。对吗?
@Nguaial 这取决于当前工作目录是什么。例如,假设您有一个 PHP 文件 /home/user/project/test.php
和一个 JSON 文件 /home/user/project/json.json
。如果您当前的工作是/home/user
,那么要运行PHP 文件,您需要输入php project/test.php
。在这种情况下,PHP 文件需要将 JSON 文件引用为 project/test.json
,因为相对路径是相对于当前工作目录的,不一定是 PHP 文件的父目录。【参考方案3】:
最优雅的解决方案:
$shipments = json_decode(file_get_contents("shipments.js"), true);
print_r($shipments);
请记住,json 文件必须以没有 BOM 的 UTF-8 编码。如果文件有 BOM,则 json_decode 将返回 NULL。
或者:
$shipments = json_encode(json_decode(file_get_contents("shipments.js"), true));
echo $shipments;
【讨论】:
非常棒,但是整个物料清单 (BOM) 的事情让我完全糊涂了。呃……你在说什么?我是唯一一个对使用神秘无法解释的缩写感到恼火的人吗?可以使用缩写,但请说明首次使用时 (WFU)...谢谢。 BOM = 字节顺序标记。 en.wikipedia.org/wiki/Byte_order_mark 如果您在 mac 和 pc 上都使用 json,则典型的问题是,因为它们使用不同的默认文本格式。 本帖不尝试回答已发布的问题【参考方案4】:试试
<?php
$string = file_get_contents("/home/michael/test.json");
$json_a = json_decode($string,true);
foreach ($json_a as $key => $value)
echo $key . ':' . $value;
?>
【讨论】:
Try This 答案在 *** 上的价值很低,因为它们对 OP 和未来的研究人员的教育作用很小。如果您打算在页面上留下这个答案,请说明您的答案是如何工作的以及为什么它是可取的。 BoltClock 的回答证明,这个回答对于问题的样本数据是不正确的。 它如何迭代嵌套的多维度数组【参考方案5】:没有人指出你开始的“标签”是错误的,这完全超出了我的理解。您正在使用 创建一个对象,而您可以使用 [] 创建一个数组。
[ // <-- Note that I changed this
"name" : "john", // And moved the name here.
"status":"Wait"
,
"name" : "Jennifer",
"status":"Active"
,
"name" : "James",
"status":"Active",
"age":56,
"count":10,
"progress":0.0029857,
"bad":0
] // <-- And this.
通过此更改,json 将被解析为数组而不是对象。有了这个数组,你可以做任何你想做的事情,比如循环等。
【讨论】:
你是正确的指出数组的东西。 哦,我的。我应该补充一点,您似乎在转换为数组时删除了 OP 的 json 中的键。所以OP是对的。 “但是因为我不知道名字(比如 John、Jennifer)和所有可用的键”。他似乎不知道密钥,所以遍历集合的唯一方法是循环。这种告诉我他不会直接通过键访问值。 这篇文章未能回答如何解析 json 字符串并从未知的第一级键访问子数组元素的问题。这不是答案,应该是问题下的评论。几乎看起来您建议应该读取该文件,然后通过字符串函数对其进行变异以满足您的偏好。我不明白。 不,我指出文件的结构是错误的,因为他正在阅读它。因此它确实回答了这个问题。而且您似乎确实不明白,因为我对字符串函数只字未提。这太傻了。【参考方案6】:试试这个
$json_data = '
"John":
"status":"Wait"
,
"Jennifer":
"status":"Active"
,
"James":
"status":"Active",
"age":56,
"count":10,
"progress":0.0029857,
"bad":0
';
$decode_data = json_decode($json_data);
foreach($decode_data as $key=>$value)
print_r($value);
【讨论】:
Try This 答案在 *** 上的价值很低,因为它们对 OP 和未来的研究人员的教育作用很小。如果您打算在页面上留下这个答案,请说明您的答案是如何工作的以及为什么它是可取的。 OP 要求解析来自 JSON 文件的数据,而不是来自代码中变量的 JSON。【参考方案7】:试试:
$string = file_get_contents("/home/michael/test.json");
$json = json_decode($string, true);
foreach ($json as $key => $value)
if (!is_array($value))
echo $key . '=>' . $value . '<br />';
else
foreach ($value as $key => $val)
echo $key . '=>' . $val . '<br />';
【讨论】:
Try This 答案在 *** 上的价值很低,因为它们对 OP 和未来的研究人员的教育作用很小。如果您打算在页面上留下这个答案,请说明您的答案是如何工作的以及为什么它是可取的。【参考方案8】:更标准的答案:
$jsondata = file_get_contents(PATH_TO_JSON_FILE."/jsonfile.json");
$array = json_decode($jsondata,true);
foreach($array as $k=>$val):
echo '<b>Name: '.$k.'</b></br>';
$keys = array_keys($val);
foreach($keys as $key):
echo ' '.ucfirst($key).' = '.$val[$key].'</br>';
endforeach;
endforeach;
输出是:
Name: John
Status = Wait
Name: Jennifer
Status = Active
Name: James
Status = Active
Age = 56
Count = 10
Progress = 0.0029857
Bad = 0
【讨论】:
或者第一行可以说$data = json_decode(file_get_contents("db.json"), true);
纯代码答案在 *** 上的价值很低,因为它们对 OP 和未来的研究人员的教育作用很小。如果您打算在页面上留下这个答案,请说明您的答案是如何工作的以及为什么它是可取的。
当下面的foreach()
循环可以自己提供数据时,在这里调用array_keys()
是没有意义的。我不认为我同意“更标准”,我可以想到一些比$val
更好的变量名。【参考方案9】:
使用 foreach
循环作为键值对循环遍历 JSON。进行类型检查以确定是否需要进行更多循环。
foreach($json_a as $key => $value)
echo $key;
if (gettype($value) == "object")
foreach ($value as $key => $value)
# and so on
【讨论】:
或者更好的是,事先知道结构是什么。【参考方案10】:<?php
$json = '
"response":
"data": ["identifier": "Be Soft Drinker, Inc.", "entityName": "BusinessPartner"],
"status": 0,
"totalRows": 83,
"startRow": 0,
"endRow": 82
';
$json = json_decode($json, true);
//echo '<pre>'; print_r($json); exit;
echo $json['response']['data'][0]['identifier'];
$json['response']['data'][0]['entityName']
echo $json['response']['status'];
echo $json['response']['totalRows'];
echo $json['response']['startRow'];
echo $json['response']['endRow'];
?>
【讨论】:
纯代码答案在 *** 上的价值很低,因为它们对 OP 和未来的研究人员的教育作用很小。如果您打算在页面上留下这个答案,请说明您的答案是如何工作的以及为什么它是可取的。 与其忽略 OP 提供的示例数据,请尝试以与发布的问题直接直接相关的方式回答问题。【参考方案11】:试试看:
foreach ($json_a as $key => $value)
echo $key, ' : ';
foreach($value as $v)
echo $v." ";
【讨论】:
Try This 答案在 *** 上的价值很低,因为它们对 OP 和未来的研究人员的教育作用很小。如果您打算在页面上留下这个答案,请说明您的答案是如何工作的以及为什么它是可取的。【参考方案12】:当你解码一个 json 字符串时,你会得到一个对象。不是数组。因此,查看您获得的结构的最佳方法是制作解码的 var_dump。 (这个 var_dump 可以帮助你理解结构,主要是在复杂的情况下)。
<?php
$json = file_get_contents('/home/michael/test.json');
$json_a = json_decode($json);
var_dump($json_a); // just to see the structure. It will help you for future cases
echo "\n";
foreach($json_a as $row)
echo $row->status;
echo "\n";
?>
【讨论】:
【参考方案13】:$json_a = json_decode($string, TRUE);
$json_o = json_decode($string);
foreach($json_a as $person => $value)
foreach($value as $key => $personal)
echo $person. " with ".$key . " is ".$personal;
echo "<br>";
【讨论】:
嗨,这可能很好地解决了问题......但如果你可以编辑你的答案并提供更多关于它的工作原理和原因的解释会很好:)不要忘记 - Stack overflow 上有很多新手,他们可以从你的专业知识中学到一两件事——对你来说显而易见的事情对他们来说可能不是。【参考方案14】:回显所有 json 值的最快方法是使用循环中的循环,第一个循环将获取所有对象,第二个循环将获取值...
foreach($data as $object)
foreach($object as $value)
echo $value;
【讨论】:
【参考方案15】:你必须像这样给予:
echo $json_a['John']['status'];
echo "<>"
echo $json_a['Jennifer']['status'];
br inside <>
结果如下:
wait
active
【讨论】:
Do Like This 答案在 *** 上的价值很低,因为它们对 OP 和未来的研究人员的教育作用很小。如果您打算在页面上留下这个答案,请说明您的答案是如何工作的以及为什么它是可取的。 这个答案似乎误解了这个问题。 OP 事先不知道“名称”键,因此它们不能被硬编码。这个答案不正确。【参考方案16】:我正在使用下面的代码将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) );
?>
【讨论】:
empty()
是不必要的开销。只需使用!json_last_error()
。此外,这无法回答 OP 提出的问题。它不是“如何将值转换为数组”,也不是“如何检查 JSON 错误”。我将此帖子标记为不是答案。
但是没有人解决如果 json 格式错误的情况,所以只有 json_decode() 是不够的,还应该检查有效的 json,它是你的思考者,如果你想要标记,我不在这里赚取积分,作为开发人员唯一的解决方案是不够的,利弊也一样,
每个答案都应该回答所提出的确切问题。如果每个答案都流向相关主题,那么 *** 页面对于研究人员来说将更难找到他们实际正在寻找的解决方案。有时我会用错误检查来打包我的答案(通常是我的 mysql 答案),因为它是正确解决方案的合理伴奏。例如,我永远不会纯粹在“我如何交叉加入”问题上发布错误说明,因为这不会回答发布的问题。你现在明白为什么你的帖子不合适了吗?它忽略了这个问题。
您发布了错误问题的正确答案。更好的地方可能包括:***.com/q/2348152/2943403 或 ***.com/q/6041741/2943403 或 ***.com/q/5970270/2943403 等等。以上是关于如何使用 PHP 解析 JSON 文件? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何将 YouTube JSON 解析为 PHP? [复制]