2010-12-03 16 views
279

Traté de analizar un archivo JSON utilizando PHP. Pero estoy atascado ahora.¿Cómo puedo analizar un archivo JSON con PHP?

Este es el contenido de mi archivo JSON:

{ 
    "John": { 
     "status":"Wait" 
    }, 
    "Jennifer": { 
     "status":"Active" 
    }, 
    "James": { 
     "status":"Active", 
     "age":56, 
     "count":10, 
     "progress":0.0029857, 
     "bad":0 
    } 
} 

Y esto es lo que he probado hasta ahora:

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

Pero debido a que no sé los nombres (como 'John', 'Jennifer') y todas las claves y valores disponibles (como 'age', 'count') de antemano, creo que necesito crear algún bucle foreach.

Agradecería un ejemplo para esto.

+34

Estás en el camino correcto. Busque la sintaxis para foreach (debe obtener claves y valores). ¡No te rindas todavía! –

+8

@Stefan Mai: 'foreach ($ variable as $ key => $ val)' debe ser lo que quieras :-) – Bojangles

+5

@JamWaffles Jaja, gracias. Esperaba que OP pudiera obtener algo de experiencia buscándolo. Upvotes porque es realmente todo lo que necesita. –

Respuesta

260

para iterar sobre una matriz multidimensional, puede utilizar 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"; 
    } 
} 

de salida:

John: 
status => Wait 
Jennifer: 
status => Active 
James: 
status => Active 
age => 56 
count => 10 
progress => 0.0029857 
bad => 0 

run on codepad

+5

¿Este enfoque ofrece alguna ventaja especial sobre foreach viejo y bueno? –

+9

@ Álvaro, obviamente. Con foreach solo puede recurse un nivel de profundidad. Con el enfoque anterior, puede recurse en una matriz multinivel. Además, todo está encapsulado en OOP, por lo que es mejor reutilizarlo y puedes simularlo fácilmente en UnitTests además de que puedes apilar iteradores con otros iteradores haciendo cosas diferentes, como limitar, almacenar en caché, filtrar, etc., además de cualquier otro iteradores personalizados que puede querer crear – Gordon

+0

bien, no había considerado que el nivel de anidación fuera variable. En tal caso, esto es más limpio que una función recursiva. –

10

Trate

<?php 
$string = file_get_contents("/home/michael/test.json"); 
$json_a=json_decode($string,true); 

foreach ($json_a as $key => $value){ 
    echo $key . ':' . $value; 
} 
?> 
7

Loop a través de la JSON con un bucle foreach como pares de valores clave. Haga la verificación de tipos para determinar si se necesita hacer más bucles.

foreach($json_a as $key => $value) { 
    echo $key; 
    if (gettype($value) == "object") { 
     foreach ($value as $key => $value) { 
      # and so on 
     } 
    } 
} 
+0

O mejor aún, sepa cuál es la estructura de antemano. –

87

No puedo creer que muchas personas estén publicando respuestas sin leer correctamente el JSON.

Si forecech itera $json_a solo, tiene un objeto de objetos. Incluso si pasa true como segundo parámetro, tiene una matriz bidimensional. Si estás recorriendo la primera dimensión, no puedes repetir la segunda dimensión de esa manera. Así que esto es incorrecto:

foreach ($json_a as $k => $v) { 
    echo $k, ' : ', $v; 
} 

hacerse eco de los estados de cada persona, intente esto:

<?php 

$string = file_get_contents("/home/michael/test.json"); 
$json_a = json_decode($string, true); 

foreach ($json_a as $person_name => $person_a) { 
    echo $person_a['status']; 
} 

?> 
+1

Si los archivos php y json están en el mismo directorio, podemos leer json con 'file_get_contents (" test.json ");' (No es necesario poner la ruta). – hyip

0

Hay que dar la siguiente manera:

echo $json_a['John']['status']; 

echo "<>" 

echo $json_a['Jennifer']['status']; 

br inside <> 

que da el resultado:

wait 
active 
4

Práctica:

foreach ($json_a as $key => $value) 
{ 
    echo $key, ' : '; 
    foreach($value as $v) 
    { 
     echo $v." "; 
    } 
} 
8

Probar:

$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 />'; 
     } 
    } 
} 
1

Cuando decodifica una cadena json, obtendrá un objeto. no es una matriz. Entonces, la mejor manera de ver la estructura que está obteniendo es hacer un var_dump de decodificación. (este var_dump puede ayudarte a entender la estructura, principalmente en casos complejos).

<?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"; 
    } 
?> 
0
$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>"; 
    } 

} 
+3

Hola, esto bien podría resolver el problema ... pero sería bueno si pudieras editar tu respuesta y darles un poco más de explicación sobre cómo y por qué funciona:) No lo olvides: hay montones de novatos en el desbordamiento de pila, y podrían aprender una o dos cosas de tu experiencia: lo que es obvio para ti podría no serlo para ellos. –

29

La solución más elegante:

$shipments = json_decode(file_get_contents("shipments.js"), true); 
print_r($shipments); 

Recuerde que el JSON-archivo tiene que ser codificado en UTF-8 sin BOM. Si el archivo tiene BOM, entonces json_decode devolverá NULL.

alternativa:

$shipments = json_encode(json_decode(file_get_contents("shipments.js"), true)); 
echo $shipments; 
+0

Bastante impresionante, pero todo el asunto de la lista de materiales (BOM) me tiene totalmente confundido. eh ... ¿de qué estás hablando? ¿Soy el único tipo molesto con las abreviaturas inexplicadas de misterio? De acuerdo para usar abreviaturas, pero por favor explique Cuando se usa por primera vez (WFU) ... gracias. – zipzit

+3

BOM = marca de orden de bytes. – swift

+1

http://en.wikipedia.org/wiki/Byte_order_mark Típico de Gotcha si estás trabajando con json tanto en mac como en PC, ya que usan diferentes formatos de texto predeterminados. – swift

13

Es completamente fuera de mí que nadie señaló que su principio "tags" son erróneas. Está creando un objeto con {}, mientras que podría crear una matriz con [].

[ // <-- 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. 

Con este cambio, el json se analizará como una matriz en lugar de como un objeto. Y con esa matriz, puede hacer lo que quiera, como bucles, etc.

+0

Tiene razón al señalar la matriz. –

+0

Oh mía. Debo agregar que pareces haber eliminado la clave en el JSON del OP al convertir a matriz. Entonces el OP es correcto. –

+0

"Pero porque no sé los nombres (como John, Jennifer) y todas las claves disponibles". Parece que no sabe las claves, por lo que la única forma de atravesar la colección es un ciclo. Este tipo de información me dice que no dirige el acceso a los valores por clave. – David

0

La forma más rápida de hacer eco de todos los valores de json es utilizando loop in loop, el primer bucle obtendrá todos los objetos y el segundo los valores ...

foreach($data as $object) { 

     foreach($object as $value) { 

      echo $value; 

     } 

    } 
5

Más respuesta estándar:

$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 '&nbsp;'.ucfirst($key).' = '.$val[$key].'</br>'; 
    endforeach; 
endforeach; 

y la salida es:

Name: John 
Status = Wait 
Name: Jennifer 
Status = Active 
Name: James 
Status = Active 
Age = 56 
Count = 10 
Progress = 0.0029857 
Bad = 0 
10

Pruebe este

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