Menu

PHP json_decode(): convertir JSON en arrays u objetos

json_decode($json, true) convierte una cadena JSON en un array asociativo de PHP; sin true obtienes objetos stdClass. Aprende los valores anidados, el manejo de errores con JSON_THROW_ON_ERROR, json_validate() y por qué json_decode devuelve null.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

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'}.

Ilustración de los lenguajes de programación de Coddy

Aprende a programar con Coddy

COMENZAR