json_decode($json, true) convierte una cadena JSON en valores de PHP, con cada objeto JSON como un array asociativo. Si omites true, los objetos JSON se convierten en objetos stdClass, que se leen con ->. Un JSON no válido da null.
Salida:
Ada
js
Ada
php
Array
(
[name] => Ada
[age] => 36
[langs] => Array
(
[0] => php
[1] => js
)
[admin] => 1
)
Los arrays JSON siempre se convierten en listas de PHP, elijas el modo que elijas. La dirección contraria, de PHP a JSON, es json_encode().
Array asociativo u objeto: true vs false
Los dos modos contienen los mismos datos; elige el que se lea mejor en tu código. Los arrays funcionan con todas las funciones de arrays (array_column, array_map, isset($data['key'])), así que la mayoría del código pasa true. Los objetos necesitan la sintaxis con llaves para las claves que no son nombres de propiedad válidos, como las claves con un guion o un número:
Salida:
Ada zero London
Ada zero London
object(stdClass)#2 (1) {
["city"]=>
string(6) "London"
}
El cuarto parámetro recibe opciones. JSON_OBJECT_AS_ARRAY también da arrays, pero solo mientras el segundo argumento sea null (su valor por defecto): json_decode($json, flags: JSON_OBJECT_AS_ARRAY) devuelve arrays, mientras que json_decode($json, false, 512, JSON_OBJECT_AS_ARRAY) sigue devolviendo objetos.
Recorrer JSON anidado
Las respuestas de las APIs suelen ser una lista de objetos dentro de un objeto. Decodifica una vez, recórrelo con foreach y usa ?? para los campos que pueden faltar:
Salida:
#1 Ada <ada@example.com> roles: admin, editor
#2 Linus <no email> roles: none
#3 Grace <grace@example.com> roles: editor
Array
(
[1] => Ada
[2] => Linus
[3] => Grace
)
Manejar JSON no válido
json_decode() devuelve null con un JSON no válido, pero null es también el resultado correcto para el texto JSON null, así que null por sí solo no te dice si falló. json_last_error_msg() da el motivo de la última llamada. La forma más limpia es JSON_THROW_ON_ERROR, que lanza una JsonException:
Salida:
NULL
Syntax error
NULL
No error
Invalid JSON: Syntax error
El tercer argumento, 512, es la profundidad máxima de anidamiento (el valor por defecto). Con argumentos con nombre puedes saltártelo: json_decode($json, true, flags: JSON_THROW_ON_ERROR).
Comprobar si una cadena es JSON válido con json_validate()
PHP 8.3 añadió json_validate(). Responde true o false sin construir los arrays decodificados, así que usa menos memoria que decodificar cuando solo necesitas un sí o un no, por ejemplo para rechazar pronto el cuerpo de una petición:
Salida:
'{"a": 1}' valid
'[1, 2, 3]' valid
'"text"' valid
'{a: 1}' invalid: Syntax error
'{\'a\': 1}' invalid: Syntax error
'' invalid: Syntax error
Si vas a usar los datos de todas formas, sáltate json_validate() y decodifica con JSON_THROW_ON_ERROR: validar primero analiza la cadena dos veces.
Leer un archivo JSON
Lee el archivo con file_get_contents() y decodifica la cadena. Este bloque escribe primero settings.json para que haya un archivo que leer:
Salida:
Theme: dark
Plugins: 2
{
"theme": "dark",
"fontSize": 16,
"plugins": [
"git",
"lint"
]
}
Por qué json_decode devuelve null: las causas habituales
JSON es más estricto que JavaScript y que la sintaxis de arrays de PHP. Todas las cadenas de abajo parecen razonables y todas devuelven null. Ejecútalo para ver el motivo de cada una, luego corrige una y vuelve a ejecutarlo:
Salida:
single quotes Syntax error
unquoted key Syntax error
trailing comma Syntax error
comment Syntax error
byte order mark Syntax error
too deep Maximum stack depth exceeded
float(1.2345678901234567E+19)
string(20) "12345678901234567890"
Una marca de orden de bytes es invisible en la mayoría de los editores y es el motivo clásico de que un archivo JSON "se vea bien" pero no se decodifique. Quítala con $text = preg_replace('/^\xEF\xBB\xBF/', '', $text); antes de decodificar.
Preguntas frecuentes
¿Cómo convierto JSON en un array en PHP?
Pasa true como segundo argumento: json_decode('{"name":"Ada"}', true) devuelve ['name' => 'Ada'], así que lees los valores con $data['name']. Sin true, los objetos JSON se convierten en objetos stdClass y escribes $data->name.
¿Por qué json_decode devuelve null?
El JSON no es válido (comillas simples, una coma final, claves sin comillas, una marca de orden de bytes), está anidado más allá del límite de profundidad, o el JSON es realmente null. Comprueba json_last_error_msg(), o decodifica con JSON_THROW_ON_ERROR para obtener una JsonException con el motivo.
¿Cómo compruebo si una cadena es JSON válido en PHP?
Desde PHP 8.3, json_validate($string) devuelve true o false sin construir el valor decodificado. En versiones anteriores, decodifícala y comprueba json_last_error() === JSON_ERROR_NONE.
¿Cómo leo un archivo JSON en PHP?
Lee el archivo y luego decodifícalo: $data = json_decode(file_get_contents('data.json'), true, flags: JSON_THROW_ON_ERROR);. file_get_contents() devuelve false si el archivo no existe, así que compruébalo primero.
¿Cómo accedo a una clave JSON con un guion en PHP?
Decodifica a array y usa $data['first-name'], o con objetos usa llaves: $obj->{'first-name'}. La misma sintaxis con llaves funciona con claves que son números, como $obj->{'0'}.