PHP Decodificando una cadena JSON


Ejemplo

La función json_decode() toma una cadena codificada en JSON como su primer parámetro y la analiza en una variable de PHP.

Normalmente, json_decode() devolverá un objeto de \ stdClass si el elemento de nivel superior en el objeto JSON es un diccionario o una matriz indexada si el objeto JSON es una matriz. También devolverá valores escalares o NULL para ciertos valores escalares, como cadenas simples, "true" , "false" y "null" . También devuelve NULL en cualquier error.

// Returns an object (The top level item in the JSON string is a JSON dictionary)
$json_string = '{"name": "Jeff", "age": 20, "active": true, "colors": ["red", "blue"]}';
$object = json_decode($json_string);
printf('Hello %s, You are %s years old.', $object->name, $object->age);
#> Hello Jeff, You are 20 years old.

// Returns an array (The top level item in the JSON string is a JSON array)
$json_string = '["Jeff", 20, true, ["red", "blue"]]';
$array = json_decode($json_string);
printf('Hello %s, You are %s years old.', $array[0], $array[1]);

Use var_dump() para ver los tipos y valores de cada propiedad en el objeto que decodificamos arriba.

// Dump our above $object to view how it was decoded
var_dump($object);

Salida (note los tipos de variables):

class stdClass#2 (4) {
 ["name"] => string(4) "Jeff"
 ["age"] => int(20)
 ["active"] => bool(true)
 ["colors"] =>
   array(2) {
     [0] => string(3) "red"
     [1] => string(4) "blue"
   }
}

Nota: Los tipos de variables en JSON se convirtieron a su equivalente de PHP.


Para devolver una matriz asociativa para objetos JSON en lugar de devolver un objeto, pase true como segundo parámetro a json_decode() .

$json_string = '{"name": "Jeff", "age": 20, "active": true, "colors": ["red", "blue"]}';
$array = json_decode($json_string, true); // Note the second parameter
var_dump($array);

Salida (note la estructura asociativa de la matriz):

array(4) {
  ["name"] => string(4) "Jeff"
  ["age"] => int(20)
  ["active"] => bool(true)
  ["colors"] =>
  array(2) {
    [0] => string(3) "red"
    [1] => string(4) "blue"
  }
}

El segundo parámetro ( $assoc ) no tiene efecto si la variable a devolver no es un objeto.

Nota: Si usa el parámetro $assoc , perderá la distinción entre una matriz vacía y un objeto vacío. Esto significa que ejecutar json_encode() en su salida descodificada de nuevo, resultará en una estructura JSON diferente.

Si la cadena JSON tiene una "profundidad" de más de 512 elementos ( 20 elementos en versiones anteriores a 5.2.3, o 128 en la versión 5.2.3 ) en recursión, la función json_decode() devuelve NULL . En las versiones 5.3 o posteriores, este límite se puede controlar mediante el tercer parámetro ( $depth ), como se explica a continuación.


Según el manual:

PHP implementa un superconjunto de JSON como se especifica en el »RFC 4627 original - también codificará y decodificará tipos escalares y NULL. RFC 4627 solo admite estos valores cuando están anidados dentro de una matriz o un objeto. Aunque este superconjunto es consistente con la definición ampliada de "texto JSON" en el »RFC 7159 más reciente (que apunta a reemplazar el RFC 4627) y » ECMA-404 , esto puede causar problemas de interoperabilidad con los analizadores JSON más antiguos que se adhieren estrictamente al RFC 4627 cuando codificando un solo valor escalar.

Esto significa que, por ejemplo, una cadena simple se considerará un objeto JSON válido en PHP:

$json = json_decode('"some string"', true);
var_dump($json, json_last_error_msg());

Salida:

string(11) "some string"
string(8) "No error"

Pero las cadenas simples, que no están en una matriz u objeto, no forman parte del estándar RFC 4627 . Como resultado, los verificadores en línea como JSLint , JSON Formatter & Validator (en modo RFC 4627) le darán un error.

Hay un tercer parámetro $depth para la profundidad de la recursión (el valor predeterminado es 512 ), lo que significa la cantidad de objetos anidados dentro del objeto original a decodificar.

Hay un cuarto parámetro de $options . Actualmente solo acepta un valor, JSON_BIGINT_AS_STRING . El comportamiento predeterminado (que deja esta opción) es convertir enteros grandes en flotantes en lugar de cadenas.

Las variantes no escritas en minúsculas de los literales verdadero, falso y nulo ya no se aceptan como entrada válida.

Así que este ejemplo:

var_dump(json_decode('tRue'), json_last_error_msg());
var_dump(json_decode('tRUe'), json_last_error_msg());
var_dump(json_decode('tRUE'), json_last_error_msg());
var_dump(json_decode('TRUe'), json_last_error_msg());
var_dump(json_decode('TRUE'), json_last_error_msg());
var_dump(json_decode('true'), json_last_error_msg());

Antes de PHP 5.6:

bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"

Y después:

NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
bool(true)
string(8) "No error"

Similar comportamiento ocurre para false y null .

Tenga en cuenta que json_decode() devolverá NULL si la cadena no se puede convertir.

$json = "{'name': 'Jeff', 'age': 20 }" ;  // invalid json 

$person = json_decode($json);
echo $person->name;    //  Notice: Trying to get property of non-object: returns null
echo json_last_error();     
#  4 (JSON_ERROR_SYNTAX)
echo json_last_error_msg(); 
#  unexpected character 

No es seguro confiar solo en que el valor de retorno sea NULL para detectar errores. Por ejemplo, si la cadena JSON no contiene nada más que "null" , json_decode() devolverá null , aunque no se haya producido ningún error.