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

时间:2015-03-27 19:38:47

标签: php json

  

这是一个一般参考问题和答案,涵盖了许多永无止境的"如何访问我的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 个答案:

答案 0 :(得分:357)

简介

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

 $data = json_decode($json);

你可能会发现:

这些是可以用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的所有内容。

查看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

这是因为:

  1. JSON完全由null
  2. 组成
  3. JSON无效 - 请检查json_last_error_msg的结果或通过JSONLint之类的内容。
  4. 它包含嵌套超过512级深度的元素。可以通过将整数作为第三个参数传递给json_decode()来覆盖此默认最大深度。
  5. 如果您需要更改最大深度,您可能正在解决错误的问题。找出您获取此类深层嵌套数据的原因(例如,您要查询生成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

答案 1 :(得分:12)

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

答案 2 :(得分:1)

// 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>";
}

答案 3 :(得分:0)

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

答案 4 :(得分:0)

上面的答案很快就结束了,我想更进一步,并从JSON中获取单个变量。我的解决办法是...

$my_json = '{"cat": "Tibbles", "dog": "Rover", "rabbit": "Flopsy"}';
extract(json_decode($my_json, true));
echo "Dog: $dog; Rabbit: $rabbit; Cat: $cat";

注意:请勿在不受信任的数据上使用,因为 extract()允许覆盖局部变量。 (我的应用程序是一个独立的分析,正在导入和导出自己的数据)。

答案 5 :(得分:0)

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

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

答案 6 :(得分:-1)

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

我只想补充一点,我在尝试加载使用 UTF8 编码的 JSON 文本文件时遇到错误,我有一个格式良好的 JSON,但 'json_decode' 总是返回 NULL,这是由于 {{3 }}。

为了解决这个问题,我做了这个 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 :(得分:-2)

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

检查以下代码,将json转换为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) );

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

答案 8 :(得分:-3)

我写了一个名为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();

请参阅the wikithe quick tutorial以熟悉它。

此外,如果您想读取JSON文件并提取其数据(似乎正在尝试执行此操作),请参见JSONFile程序包,该程序包也是我编写的。