Como extraio dados de JSON com PHP?

214

Pretende-se que seja uma pergunta e resposta de referência geral, cobrindo muitos dos intermináveis "Como acesso dados no meu JSON?" questões. Ele está aqui para lidar com os conceitos básicos gerais de decodificação de JSON em PHP e acessar os resultados.

Eu tenho o JSON:

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

Como decodificar isso em PHP e acessar os dados resultantes?

user3942918
fonte
1
Relacionado: Capaz de ver uma variável na saída de print_r (), mas não tendo certeza de como acessá-la no código , a exploração JSON interativa no contexto do PHP é possível aqui: array.include-once.org
hakre
Posso saber por que essa pergunta não é considerada uma pergunta duplicada, mesmo com 9 ou menos usuários marcados como duplicado para stackoverflow.com/questions/4343596/parsing-json-file-with-php ? M
Eu sou a pessoa mais estúpida
@IamtheMostStupidPerson Vou tentar explicar, mesmo que seu nome de usuário me faça duvidar que você o entenda;). Esta pergunta é feita e suas respostas são escritas de maneira "canônica". Como tal, é um destinatário melhor para o destino duplicado do que as outras perguntas.
Félix Gagnon-Grenier

Respostas:

428

Introdução

Primeiro, você tem uma corda. JSON não é uma matriz, um objeto ou uma estrutura de dados. JSON é um formato de serialização baseado em texto - portanto, uma string sofisticada, mas ainda assim uma string. Decodifique-o no PHP usando json_decode().

 $data = json_decode($json);

Nele você pode encontrar:

Essas são as coisas que podem ser codificadas em JSON. Ou, mais precisamente, essas são as versões do PHP das coisas que podem ser codificadas em JSON.

Não há nada de especial neles. Eles não são "objetos JSON" ou "matrizes JSON". Você decodificou o JSON - agora você tem tipos básicos de PHP todos os dias .

Os objetos serão instâncias do stdClass , uma classe interna que é apenas uma coisa genérica que não é importante aqui.


Acessando propriedades do objeto

Você acessa as propriedades de um desses objetos da mesma maneira que faria para as propriedades não estáticas públicas de qualquer outro objeto, por exemplo $object->property.

$json = '
{
    "type": "donut",
    "name": "Cake"
}';

$yummy = json_decode($json);

echo $yummy->type; //donut

Acessando elementos da matriz

Você acessa os elementos de uma dessas matrizes da mesma maneira que faria com qualquer outra matriz, por exemplo $array[0].

$json = '
[
    "Glazed",
    "Chocolate with Sprinkles",
    "Maple"
]';

$toppings = json_decode($json);

echo $toppings[1]; //Chocolate with Sprinkles

Iterar sobre isso com foreach.

foreach ($toppings as $topping) {
    echo $topping, "\n";
}


Chocolate vidrado com granulado de
bordo

Ou mexa com qualquer uma das funções de matriz embutidas .


Acessando itens aninhados

As propriedades dos objetos e os elementos das matrizes podem ser mais objetos e / ou matrizes - você pode simplesmente continuar acessando suas propriedades e membros como de costume, por exemplo $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

Passando truecomo o segundo argumento para json_decode ()

Ao fazer isso, em vez de objetos, você obtém matrizes associativas - matrizes com strings para chaves. Novamente, você acessa os elementos dos mesmos, como de costume, por exemplo $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

Acessando itens de matriz associativa

Ao decodificar um objeto JSON para uma matriz PHP associativa, é possível iterar chaves e valores usando a foreach (array_expression as $key => $value)sintaxe, por exemplo,

$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;
}

Impressões

O valor da chave 'foo' é 'foo value'
O valor da chave 'bar' é 'valor da barra'
O valor da chave 'baz' é 'valor baz'


Não sei como os dados estão estruturados

Leia a documentação para o que você está obtendo o JSON.

Veja o JSON - onde você vê colchetes {}esperando um objeto, onde você vê colchetes []esperando uma matriz.

Bata os dados decodificados com um 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);

e verifique a saída:

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
                )

        )

)

Ele lhe dirá onde você tem objetos, onde você tem matrizes, além dos nomes e valores de seus membros.

Se você só pode chegar tão longe para ele antes de se perder - ir tão longe e hit que com print_r():

print_r($yummy->toppings[0]);
stdClass Object
(
    [id] => 5002
    [type] => Glazed
)

Dê uma olhada neste prático JSON Explorer interativo .

Divida o problema em pedaços mais fáceis de entender.


json_decode() retorna null

Isso acontece porque:

  1. O JSON consiste inteiramente apenas disso null,.
  2. O JSON é inválido - verifique o resultado json_last_error_msgou coloque-o em algo como JSONLint .
  3. Ele contém elementos aninhados com mais de 512 níveis de profundidade. Essa profundidade máxima padrão pode ser substituída passando um número inteiro como o terceiro argumento para json_decode().

Se você precisar alterar a profundidade máxima, provavelmente está resolvendo o problema errado. Descubra por que você está recebendo dados tão profundamente aninhados (por exemplo, o serviço que você está consultando que está gerando o JSON tem um bug) e faça com que isso não aconteça.


O nome da propriedade do objeto contém um caractere especial

Às vezes, você terá um nome de propriedade de objeto que contém algo como um hífen -ou sinal de arroba @que não pode ser usado em um identificador literal. Em vez disso, você pode usar uma string literal dentro de chaves para endereçá-la.

$json = '{"@attributes":{"answer":42}}';
$thing = json_decode($json);

echo $thing->{'@attributes'}->answer; //42

Se você tiver um número inteiro como propriedade, consulte: Como acessar as propriedades do objeto com nomes como números inteiros? como referência.


Alguém colocou JSON no seu JSON

É ridículo, mas acontece - há JSON codificado como uma sequência dentro do seu JSON. Decode, acesso a string como de costume, decodificação que , e, eventualmente, chegar ao que você precisa.

$json = '
{
    "type": "donut",
    "name": "Cake",
    "toppings": "[{ \"type\": \"Glazed\" }, { \"type\": \"Maple\" }]"
}';

$yummy = json_decode($json);
$toppings = json_decode($yummy->toppings);

echo $toppings[0]->type; //Glazed

Os dados não cabem na memória

Se o seu JSON for muito grande para json_decode()ser manipulado imediatamente, as coisas começam a ficar complicadas. Vejo:


Como classificá-lo

Veja: Referência: todas as maneiras básicas de classificar matrizes e dados em PHP .

user3942918
fonte
apenas tropeçou nesta resposta e constatei que o link para array.include-once.org está quebrado.
Jeff
@ Jeff Obrigado. Que vergonha. Eu removi o link.
user3942918
sim, considerando o nome do link e como você o descreveu, parece uma chatice de verdade.
Jeff
A única coisa que falta nessa solução é como extrair dados de outro arquivo json. Eu recomendaria esta solução: stackoverflow.com/questions/19758954/…
Ishan Srivastava
Isso é ótimo. Obrigado.
David Kariuki
17

Você pode usar json_decode () para converter uma string json em um objeto / matriz PHP.

Por exemplo.

Entrada:

$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';

var_dump(json_decode($json));
var_dump(json_decode($json, true));

Resultado:

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)
}

Alguns pontos a serem lembrados:

  • json_decoderequer que a sequência seja válida, caso jsoncontrário ela retornará NULL.
  • No caso de uma falha na decodificação, json_last_error()pode ser usado para determinar a natureza exata do erro.
  • Certifique-se de transmitir o utf8conteúdo ou json_decodepode errar e retornar um NULLvalor.
Mohd Abdul Mujib
fonte
bem, eles podem não ter gostado de sua simplicidade, no entanto. Você sempre pode votar;)
Mohd Abdul Mujib
1
Provavelmente, o motivo mais provável é que ele já foi respondido e parece que @MohdAbdulMujib está atrás de um representante gratuito #
Isaac
3
@ Isaac Algumas pessoas podem não gostar muito de ler o manual inteiro quando querem começar a usar a função. Caso contrário, seria melhor ler o documento oficial. O ponto principal do SO é a simplicidade em que as respostas são fornecidas. IMHO
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>";
}
Sayeed amin
fonte
1

Podemos decodificar json string em array usando a função json_decode no php

1) json_decode ($ json_string) // retorna o objeto

2) json_decode ($ json_string, true) // retorna o array

$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
Kankatala Krishna
fonte
0

Considere usar JSONPath https://packagist.org/packages/flow/jsonpath

Há uma explicação bastante clara de como usá-lo e analisar um arquivo JSON, evitando todos os loops propostos. Se você está familiarizado com XPathpara XMLque você vai começar a amar esta abordagem.

Paul Burilichev
fonte
-1

Eu escrevi um pacote chamado JSON( GitHub , Packagist ). Se você deseja evitar sobrecargas no uso de json_*funções, tente.

Exemplo

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

Veja o wiki ou o tutorial rápido para se familiarizar com ele.

Além disso, se você quiser ler arquivos JSON e extrair seus dados (como parece que você está tentando fazer isso), consulte JSONFile pacote , que eu escrevi também.

MAChitgarha
fonte
-2

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

Verifique o código abaixo para converter json em array PHP. Se o JSON estiver correto, ele json_decode()funcionará bem e retornará uma matriz. Mas, se o JSON estiver mal formado, ele retornará 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) );

Se JSON malformado e você estiver esperando apenas uma matriz, poderá usar esta função,

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

Se JSON malformado e você desejar interromper a execução do código, poderá usar esta função,

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

Você pode usar qualquer função depende de sua exigência,

harish sharma
fonte