json_decode
, que mapea el objeto JSON en una variable de PHP de tipo objeto stdClass:
$jsonPHP = json_decode($respuestaJSON);
El verdadero trauma es cuando llega la hora de tratar de acceder al contenido de una variable JSON en PHP, especialmente si como yo estais más habituados a JavaScript que a PHP. Por ejemplo, veamos como parsear el siguiente objeto JSON en una variable y tratar de hacer cosas con sus datos:
{ "blog" : { "titulo":"Borrowbits" }, "usuario": { "nombre":"Angel", "permisos":"Admin" }, "usuario": { "nombre":"Vicente", "permisos":"Admin" }, "usuario": { "nombre":"Dario", "permisos":"Autor", "articulos":16 } }
Una vez le hemos aplicado json_decode
podemos observar el contenido de la variable $jsonPHP con var_dump($jsonPHP)
, que nos muestra la estructura del objeto.
Para acceder a un elemento en particular utilizamos la siguiente sintaxis:
$jsonPHP -> blog -> titulo
Para acceder a los permisos de cada usuario podemos utilizar foreach con la siguiente sintaxis:
foreach ($jsonPHP->usuario as $user){ echo "$user->nombre => $user->permisos <br />"; }
Sin embargo, ¿qué ocurre cuando tenemos varios niveles de profundidad? Es decir, si el objeto JSON contiene varios objetos JSON no podremos acceder a ellos de forma «automática» a menos que conozcamos la estructura del objeto o apliquemos algún bucle recursivo. En realidad json_decode tiene un parámetro llamado depth que permite definir la profundidad de la recursión, pero ello implicaría conocer de antemano cuántos niveles de objetos existen y no siempre podría ser así. Por ejemplo:
json_decode($respuestaJSON, FALSE, 512);
Donde 512 es el máximo nivel de iteración recursiva y FALSE hace referencia a la conversión del objeto en un array asociativo.
Veamos otras formas de iterar dentro del objeto JSON parseado en la variable PHP. Sea el objeto:
{ "blog" : { "titulo":"Borrowbits" }, "usuario": { "nombre":"Angel", "permisos":"Admin" "articulos": { "php":"12", "ia": 5, "android":8 } } ... }
Aquí el ítem articulos
contiene otro objeto JSON. En este caso conociendo la estructura podemos encadenar algunos foreach
de la siguiente forma. En este caso para listar los artículos sobre PHP que ha escrito un autor:
foreach ($jsonPHP->usuario as $user){ foreach($user->articulos as $article){ echo "$user->nombre => $article->android <br />"; }
Esta última forma que os voy a proponer no la he testado, pero debe funcionar conozcamos o no la estructura interna del objeto. Se trata de utilizar un iterador recursivo como el que provee la clase RecursiveIteratorIterator. Os daréis cuenta de que ahora json_decode
tiene el segundo parámetro: TRUE
. Lo que hace es un tratamiento de la variable como array asociativo para poder pasárselo a RecursiveArrayIterator
:
$jsonIterator = new RecursiveIteratorIterator( new RecursiveArrayIterator(json_decode($jsonPHP, TRUE)), RecursiveIteratorIterator::SELF_FIRST); foreach ($jsonIterator as $key => $val) { if(is_array($val)) { echo "$key: <br />"; } else { echo "$key => $val <br />"; } }
Y en el output obtendríamos el contenido completo de la variable:
Blog: titulo => Borrowbits Usuario: nombre => Angel permisos => admin articulos: php => 12 ia => 5 android => 8 Usuario: nombre => Vicente permisos =>admin ...
Hola, felicitaciones por la web, me parece muy interesante tu artículo, pero en mi caso, estoy trabajando con un api que me devuelve un json bastante bastante complejo,array de array de array de array…. estoy intentando utilizar recursiveItinerator y si sigo el ejemplo, lo muestra perfectamente, pero mi pregunta es, cómo en vez de mostrar el contenido con un echo, puedo almacenarlo en un array, es decir en vez de
echo «$key: «;
echo «$key => $val «;
algo como esto pero aquí sólo me muestra una iteración, obviamente la última, porque va reescribiendo.
foreach ($jsonIterator as $key => $val) {
if(is_array($val)) {
$array[‘item’][$key]=$key;
} else {
$array[‘item’][$key]=$val;
}
Gracias, saludos