Buscar..


Introducción

JSON ( JavaScript Object Notation ) es una forma independiente de plataforma y lenguaje de serializar objetos en texto plano. Debido a que se usa a menudo en la web y también lo es PHP, hay una extensión básica para trabajar con JSON en PHP.

Sintaxis

  • cadena json_encode (valor mezclado de $ [, int $ options = 0 [, int $ depth = 512]])
  • json_decode mixto (string $ json [, bool $ assoc = false [, int $ depth = 512 [, int $ options = 0]]])

Parámetros

Parámetro Detalles
json_encode -
valor El valor que se codifica. Puede ser de cualquier tipo excepto un recurso. Todos los datos de cadena deben estar codificados en UTF-8.
opciones Máscara de bits consistente en JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT El comportamiento de estas constantes se describe en la página de constantes JSON .
profundidad Establecer la profundidad máxima. Debe ser mayor que cero.
json_decode -
json La cadena json está siendo decodificada. Esta función solo funciona con cadenas codificadas en UTF-8.
asoc La función debe devolver el conjunto asociativo en lugar de los objetos.
opciones Máscara de bits de las opciones de decodificación JSON. Actualmente solo se admite JSON_BIGINT_AS_STRING (el valor predeterminado es convertir enteros grandes como flotantes)

Observaciones

  • El manejo de json_decode de JSON no válido es muy inestable, y es muy difícil determinar de manera confiable si la decodificación tuvo éxito, json_decode devuelve nulo para una entrada no válida, aunque null también es un objeto perfectamente válido para que JSON decodifique. Para evitar este tipo de problemas, siempre debe llamar a json_last_error cada vez que lo use.

Decodificando una cadena JSON

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.

Codificar una cadena JSON

La función json_encode convertirá una matriz PHP (o, desde PHP 5.4, un objeto que implementa la interfaz JsonSerializable ) en una cadena codificada en JSON. Devuelve una cadena codificada en JSON en caso de éxito o FALSE en caso de error.

$array = [
    'name' => 'Jeff',
    'age' => 20,
    'active' => true,
    'colors' => ['red', 'blue'],
    'values' => [0=>'foo', 3=>'bar'],
];

Durante la codificación, los tipos de datos de PHP, cadena, entero y booleano se convierten a su equivalente JSON. Las matrices asociativas se codifican como objetos JSON y, cuando se llaman con argumentos predeterminados, las matrices indexadas se codifican como matrices JSON. (A menos que las claves de matriz no sean una secuencia numérica continua que comience desde 0, en cuyo caso la matriz se codificará como un objeto JSON).

echo json_encode($array);

Salida:

{"name":"Jeff","age":20,"active":true,"colors":["red","blue"],"values":{"0":"foo","3":"bar"}}

Argumentos

Desde PHP 5.3, el segundo argumento de json_encode es una máscara de bits que puede ser una o más de las siguientes.

Al igual que con cualquier máscara de bits, se pueden combinar con el operador binario OR | .

PHP 5.x 5.3

JSON_FORCE_OBJECT

Fuerza la creación de un objeto en lugar de una matriz.

$array = ['Joel', 23, true, ['red', 'blue']];
echo json_encode($array);
echo json_encode($array, JSON_FORCE_OBJECT);

Salida:

["Joel",23,true,["red","blue"]]
{"0":"Joel","1":23,"2":true,"3":{"0":"red","1":"blue"}}

JSON_HEX_TAG , JSON_HEX_AMP , JSON_HEX_APOS , JSON_HEX_QUOT

Asegura las siguientes conversiones durante la codificación:

Constante Entrada Salida
JSON_HEX_TAG < \u003C
JSON_HEX_TAG > \u003E
JSON_HEX_AMP & \u0026
JSON_HEX_APOS ' \u0027
JSON_HEX_QUOT " \u0022
$array = ["tag"=>"<>", "amp"=>"&", "apos"=>"'", "quot"=>"\""];
echo json_encode($array);
echo json_encode($array, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);

Salida:

{"tag":"<>","amp":"&","apos":"'","quot":"\""}
{"tag":"\u003C\u003E","amp":"\u0026","apos":"\u0027","quot":"\u0022"}
PHP 5.x 5.3

JSON_NUMERIC_CHECK

Asegura que las cadenas numéricas se conviertan a enteros.

$array = ['23452', 23452];
echo json_encode($array);
echo json_encode($array, JSON_NUMERIC_CHECK);

Salida:

["23452",23452]    
[23452,23452]
PHP 5.x 5.4

JSON_PRETTY_PRINT

Hace el JSON fácilmente legible

$array = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
echo json_encode($array);
echo json_encode($array, JSON_PRETTY_PRINT);

Salida:

{"a":1,"b":2,"c":3,"d":4}
{
    "a": 1,
    "b": 2,
    "c": 3,
    "d": 4
}

JSON_UNESCAPED_SLASHES

Incluye barras inclinadas / salientes en la salida

$array = ['filename' => 'example.txt', 'path' => '/full/path/to/file/'];
echo json_encode($array);
echo json_encode($array, JSON_UNESCAPED_SLASHES);

Salida:

{"filename":"example.txt","path":"\/full\/path\/to\/file"}
{"filename":"example.txt","path":"/full/path/to/file"}

JSON_UNESCAPED_UNICODE

Incluye caracteres codificados en UTF8 en la salida en lugar de cadenas codificadas en \u

$blues = ["english"=>"blue", "norwegian"=>"blå", "german"=>"blau"];
echo json_encode($blues);
echo json_encode($blues, JSON_UNESCAPED_UNICODE);

Salida:

{"english":"blue","norwegian":"bl\u00e5","german":"blau"}
{"english":"blue","norwegian":"blå","german":"blau"}
PHP 5.x 5.5

JSON_PARTIAL_OUTPUT_ON_ERROR

Permite que la codificación continúe si se encuentran algunos valores no codificables.

$fp = fopen("foo.txt", "r");
$array = ["file"=>$fp, "name"=>"foo.txt"];
echo json_encode($array); // no output
echo json_encode($array, JSON_PARTIAL_OUTPUT_ON_ERROR);

Salida:

{"file":null,"name":"foo.txt"}
PHP 5.x 5.6

JSON_PRESERVE_ZERO_FRACTION

Asegura que los flotadores estén siempre codificados como flotadores.

$array = [5.0, 5.5];
echo json_encode($array);
echo json_encode($array, JSON_PRESERVE_ZERO_FRACTION);

Salida:

[5,5.5]
[5.0,5.5]
PHP 7.x 7.1

JSON_UNESCAPED_LINE_TERMINATORS

Cuando se usa con JSON_UNESCAPED_UNICODE , vuelve al comportamiento de versiones anteriores de PHP y no escapa a los caracteres U + 2028 LINE SEPARATOR y U + 2029 PARAGRAPH SEPARATOR. Aunque son válidos en JSON, estos caracteres no son válidos en JavaScript, por lo que el comportamiento predeterminado de JSON_UNESCAPED_UNICODE se cambió en la versión 7.1.

$array = ["line"=>"\xe2\x80\xa8", "paragraph"=>"\xe2\x80\xa9"];
echo json_encode($array, JSON_UNESCAPED_UNICODE);
echo json_encode($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS);

Salida:

{"line":"\u2028","paragraph":"\u2029"}
{"line":"
","paragraph":"
"}

Depuración de errores JSON

Cuando json_encode o json_decode no puede analizar la cadena proporcionada, devolverá false . PHP en sí mismo no generará ningún error o advertencia cuando esto suceda, la responsabilidad del usuario es utilizar las funciones json_last_error () y json_last_error_msg () para verificar si ocurrió un error y actuar en consecuencia en su aplicación (depurarlo, mostrar un mensaje de error , etc.).

El siguiente ejemplo muestra un error común cuando se trabaja con JSON, un error al descodificar / codificar una cadena JSON (por ejemplo, al pasar una cadena codificada en UTF-8 incorrecta) .

// An incorrectly formed JSON string
$jsonString = json_encode("{'Bad JSON':\xB1\x31}");

if (json_last_error() != JSON_ERROR_NONE) {
    printf("JSON Error: %s", json_last_error_msg());
}

#> JSON Error: Malformed UTF-8 characters, possibly incorrectly encoded

json_last_error_msg

json_last_error_msg() devuelve un mensaje legible por humanos del último error que se produjo al intentar codificar / decodificar una cadena.

  • Esta función siempre devolverá una cadena , incluso si no se produjo ningún error.
    La cadena predeterminada que no es de error es No Error
  • Devolverá false si se produce algún otro error (desconocido)
  • Tenga cuidado al usar esto en bucles, ya que json_last_error_msg se anulará en cada iteración.

Solo debe usar esta función para mostrar el mensaje, no para probar en las declaraciones de control.

// Don't do this:
if (json_last_error_msg()){} // always true (it's a string)
if (json_last_error_msg() != "No Error"){} // Bad practice

// Do this: (test the integer against one of the pre-defined constants)
if (json_last_error() != JSON_ERROR_NONE) {
    // Use json_last_error_msg to display the message only, (not test against it)
    printf("JSON Error: %s", json_last_error_msg());
}

Esta función no existe antes de PHP 5.5. Aquí hay una implementación de polyfill:

if (!function_exists('json_last_error_msg')) {
    function json_last_error_msg() {
        static $ERRORS = array(
            JSON_ERROR_NONE => 'No error',
            JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
            JSON_ERROR_STATE_MISMATCH => 'State mismatch (invalid or malformed JSON)',
            JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
            JSON_ERROR_SYNTAX => 'Syntax error',
            JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
        );

        $error = json_last_error();
        return isset($ERRORS[$error]) ? $ERRORS[$error] : 'Unknown error';
    }
}

json_last_error

json_last_error() devuelve un entero asignado a una de las constantes predefinidas provistas por PHP.

Constante Sentido
JSON_ERROR_NONE No ha ocurrido ningún error
JSON_ERROR_DEPTH Se ha superado la profundidad máxima de pila.
JSON_ERROR_STATE_MISMATCH JSON inválido o mal formado
JSON_ERROR_CTRL_CHAR Error de carácter de control, posiblemente codificado incorrectamente
JSON_ERROR_SYNTAX Error de sintaxis (desde PHP 5.3.3)
JSON_ERROR_UTF8 Caracteres UTF-8 con formato incorrecto, posiblemente codificados incorrectamente (desde PHP 5.5.0)
JSON_ERROR_RECURSION Una o más referencias recursivas en el valor a codificar
JSON_ERROR_INF_OR_NAN Uno o más valores NAN o INF en el valor a codificar
JSON_ERROR_UNSUPPORTED_TYPE Se dio un valor de un tipo que no puede ser codificado

Usando JsonSerializable en un objeto

PHP 5.x 5.4

Al crear API REST, es posible que deba reducir la información de un objeto que se pasará a la aplicación cliente. Para este propósito, este ejemplo ilustra cómo usar la interfaz JsonSerialiazble .

En este ejemplo, la clase User realidad extiende un objeto modelo DB de un ORM hipotético.

class User extends Model implements JsonSerializable {
    public $id;
    public $name;
    public $surname;
    public $username;
    public $password;
    public $email;
    public $date_created;
    public $date_edit;
    public $role;
    public $status;

    public function jsonSerialize() {
        return [
            'name' => $this->name,
            'surname' => $this->surname,
            'username' => $this->username
        ];
    }
}

Agregue la implementación JsonSerializable a la clase, proporcionando el método jsonSerialize() .

public function jsonSerialize()

Ahora, en su controlador de aplicación o script, al pasar el Usuario de objeto a json_encode() obtendrá la matriz codificada de json de retorno del método jsonSerialize() lugar de todo el objeto.

json_encode($User);

Volverá

{"name":"John", "surname":"Doe", "username" : "TestJson"}

Ejemplo de valores de propiedades.

Esto reducirá la cantidad de datos devueltos desde un punto final RESTful y permitirá excluir las propiedades del objeto de una representación json.


Usando propiedades privadas y protegidas con json_encode()

Para evitar el uso de JsonSerializable, también es posible usar propiedades privadas o protegidas para ocultar la información de clase de la json_encode() de json_encode() . La clase entonces no necesita implementar \ JsonSerializable.

La función json_encode () solo codificará las propiedades públicas de una clase en JSON.

<?php

class User {
    // private properties only within this class
    private $id;
    private $date_created;
    private $date_edit;

    // properties used in extended classes
    protected $password;
    protected $email;
    protected $role;
    protected $status;

    // share these properties with the end user        
    public $name;
    public $surname;
    public $username;

    // jsonSerialize() not needed here
}        

$theUser = new User();

var_dump(json_encode($theUser));

Salida:

string(44) "{"name":null,"surname":null,"username":null}"

Encabezado json y la respuesta devuelta

Añadiendo un encabezado con tipo de contenido como JSON:

<?php
 $result = array('menu1' => 'home', 'menu2' => 'code php', 'menu3' => 'about');

//return the json response :
header('Content-Type: application/json');  // <-- header declaration
echo json_encode($result, true);    // <--- encode
exit();

El encabezado está allí para que su aplicación pueda detectar qué datos se devolvieron y cómo debería manejarlos.
Tenga en cuenta que: el encabezado de contenido es solo información sobre el tipo de datos devueltos.

Si está utilizando UTF-8, puede usar:

header("Content-Type: application/json;charset=utf-8");

Ejemplo jQuery:

$.ajax({
        url:'url_your_page_php_that_return_json'        
    }).done(function(data){
        console.table('json ',data);
        console.log('Menu1 : ', data.menu1);
    });


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow