Correct way to get JSON "Sub Array’s" values in PHP

Asked

Viewed 114 times

0

I made the following code:

<?php

//dados de um arquivo JSON
$json_str = '[ {
  "documentoId" : 1057615,
  "nome" : "1542980818602.pdf",
  "assunto" : "AQUI FICA O ASSUNTO DO DOCUMENTO",
  "dataEnvio" : "23/11/2018 10:46:58",
  "tipoDocumento" : {
    "tipoDocumentoId" : 137,
    "nome" : "Nome de um Tipo"
  },
  "link" : null
}, {
  "documentoId" : 1057748,
  "nome" : "1542983033040.pdf",
  "assunto" : "FICA AQUI OUTRO ASSUNTO",
  "dataEnvio" : "23/11/2018 11:23:53",
  "tipoDocumento" : {
    "tipoDocumentoId" : 105,
    "nome" : "Nome de Outro Tipo"
  },
  "link" : null
}, {
  "documentoId" : 1064570,
  "nome" : "1543494201384.pdf",
  "assunto" : "ESCREVO AQUI MAIS OUTRO ASSUNTO",
  "dataEnvio" : "29/11/2018 09:23:21",
  "tipoDocumento" : {
    "tipoDocumentoId" : 135,
    "nome" : "Outro Tipo Aqui"
  },
  "link" : null
}, {
  "documentoId" : 1064592,
  "nome" : "1543494685352.pdf",
  "assunto" : "OUTRO ASSUNTO ESCRITO AQUI ",
  "dataEnvio" : "29/11/2018 09:31:25",
  "tipoDocumento" : {
    "tipoDocumentoId" : 134,
    "nome" : "Mais Um Tipo"
  },
  "link" : null
} ]';

//faz o parsing na string, gerando um objeto PHP
$jsonObj = json_decode($json_str);

//navega pelos elementos do array, imprimindo os objetos
foreach ( $jsonObj as $e )
    {

        if (property_exists($e, "tipoDocumento")) { 
        $deps = $e->tipoDocumento;
        foreach ( $deps as $d );
        echo "<div>Tipo de Documento: $d - Descrição: $e->assunto - Data de envio: $e->dataEnvio - Nome: $e->nome </div>";
    }
    }
?> 

I’d like to take the value of tipoDocumento > nome. The code returns:

inserir a descrição da imagem aqui

Is working perfectly.

But I believe that is not the correct solution to "filter" these values, because there is something that is defining that I want to take the value of tipoDocumento > nome and yet it’s being perfectly.

Notice that the same object tipoDocumento possesses within it tipoDocumentoId and nome, and yet it is ignoring and being printed the value of tipoDocumento > nome perfectly.

"tipoDocumento" : {
        "tipoDocumentoId" : 137,
        "nome" : "Nome de um Tipo"
      },

What is the correct way to take these values?

And if instead of tipoDocumento > nome I wanted to tipoDocumento > tipoDocumentoId, how would I set it?

1 answer

2


The problem is in this foreach:

foreach ( $deps as $d );

Notice the semicolon at the end. This means that this foreach is "empty" (i.e., it iterates by $deps but does nothing in every iteration).


In doing $deps = $e->tipoDocumento;, the variable $deps has an object like this:

"tipoDocumento" : {
  "tipoDocumentoId" : 137,
  "nome" : "Nome de um Tipo"
},

So you make a foreach in it, but doing nothing within this foreach. That is, in the first iteration, the variable $d contains the value 137, but nothing is done with it (remember, because of the semicolon, the body of the foreach is empty). Then, in the second iteration, the variable $d contains the value "Nome de um Tipo", but nothing is done with it either.

After the end of the foreach, the variable $d will have the value of the last entered element (in this case, the value of the "name" key). Therefore echo then prints the value of this key and everything "seems to work".

This behavior (from the variable continue with the value of the last element of the array after the end of the foreach) is described in documentation:

Reference of a $value and the last array element remain Even after the foreach loop


If you don’t want to go through all the values of a given object and only want some specific values, don’t use foreach. Just access each value directly. For example, if you only want the tipoDocumentoId:

foreach ( $jsonObj as $e ) {
    if (property_exists($e, "tipoDocumento")) {
        $deps = $e->tipoDocumento;
        echo "<div>Tipo de Documento ID: $deps->tipoDocumentoId - Descrição: $e->assunto - Data de envio: $e->dataEnvio - Nome: $e->nome </div>";
    }
}

Exit:

<div>Tipo de Documento ID: 137 - Descrição: AQUI FICA O ASSUNTO DO DOCUMENTO - Data de envio: 23/11/2018 10:46:58 - Nome: 1542980818602.pdf </div>
<div>Tipo de Documento ID: 105 - Descrição: FICA AQUI OUTRO ASSUNTO - Data de envio: 23/11/2018 11:23:53 - Nome: 1542983033040.pdf </div>
<div>Tipo de Documento ID: 135 - Descrição: ESCREVO AQUI MAIS OUTRO ASSUNTO - Data de envio: 29/11/2018 09:23:21 - Nome: 1543494201384.pdf </div>
<div>Tipo de Documento ID: 134 - Descrição: OUTRO ASSUNTO ESCRITO AQUI  - Data de envio: 29/11/2018 09:31:25 - Nome: 1543494685352.pdf </div>

Notice I removed the foreach and when printing I used $deps->tipoDocumentoId, that takes the value of the key "tipoDocumentoId". If you want to take the key value "nome", use $deps->nome.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.