Recherche…


Introduction

JSON ( JavaScript Object Notation ) est un moyen indépendant de la plate-forme et de la langue de sérialiser les objets en texte brut. Comme il est souvent utilisé sur le Web, de même que PHP, il existe une extension de base pour travailler avec JSON en PHP.

Syntaxe

  • string json_encode (mixed $ value [, int $ options = 0 [, int $ depth = 512]])
  • mixed json_decode (string $ json [, bool $ assoc = false [, int $ depth = 512 [, int $ options = 0]]]

Paramètres

Paramètre Détails
json_encode -
valeur La valeur en cours de codage Peut être n'importe quel type sauf une ressource. Toutes les données de chaîne doivent être codées en UTF-8.
options Bitmask constitué de JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_PRESERVE_ZERO_FRACTION, JSON_UNESCAPED_UNICODE, JSON_UNESCAPED_UNICODE, JSON_UNTIAP_ALCODE. Le comportement de ces constantes est décrit sur la page des constantes JSON .
profondeur Définissez la profondeur maximale. Doit être supérieur à zéro.
json_decode -
json La chaîne json étant décodée. Cette fonction ne fonctionne qu'avec les chaînes codées UTF-8.
assoc La fonction devrait-elle retourner un tableau associatif au lieu d'objets.
options Bitmask des options de décodage JSON. Actuellement, seul JSON_BIGINT_AS_STRING est pris en charge (par défaut, les gros entiers sont utilisés comme flottants)

Remarques

  • Le traitement par json_decode de JSON invalide est très flou, et il est très difficile de déterminer de manière fiable si le décodage a réussi, json_decode renvoie null pour une entrée non valide, même si null est également un objet parfaitement valide pour que JSON le décode. Pour éviter de tels problèmes, vous devez toujours appeler json_last_error chaque fois que vous l'utilisez.

Décoder une chaîne JSON

La fonction json_decode() prend comme premier paramètre une chaîne codée JSON et l’analyse en une variable PHP.

En règle générale, json_decode() renvoie un objet de \ stdClass si l'élément de niveau supérieur de l'objet JSON est un dictionnaire ou un tableau indexé si l'objet JSON est un tableau. Il renverra également des valeurs scalaires ou NULL pour certaines valeurs scalaires, telles que des chaînes simples, "true" , "false" et "null" . Il renvoie également NULL sur toute erreur.

// 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]);

Utilisez var_dump() pour afficher les types et les valeurs de chaque propriété sur l'objet que nous avons décodé ci-dessus.

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

Sortie (notez les types 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"
   }
}

Note: Les types de variables dans JSON ont été convertis en équivalent PHP.


Pour renvoyer un tableau associatif pour les objets JSON au lieu de renvoyer un objet, transmettez true comme second paramètre à 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);

Sortie (notez la structure associative du tableau):

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

Le second paramètre ( $assoc ) n'a aucun effet si la variable à retourner n'est pas un objet.

Remarque: Si vous utilisez le paramètre $assoc , vous perdrez la distinction entre un tableau vide et un objet vide. Cela signifie que l'exécution de json_encode() sur votre sortie décodée entraînera une structure JSON différente.

Si la chaîne JSON a une "profondeur" de plus de 512 éléments ( 20 éléments dans les versions antérieures à 5.2.3, ou 128 dans la version 5.2.3 ) en récursivité, la fonction json_decode() renvoie NULL . Dans les versions 5.3 ou ultérieures, cette limite peut être contrôlée en utilisant le troisième paramètre ( $depth ), comme indiqué ci-dessous.


Selon le manuel:

PHP implémente un sur-ensemble de JSON tel que spécifié dans l'original »RFC 4627 - il va également encoder et décoder les types scalaires et NULL. La RFC 4627 prend uniquement en charge ces valeurs lorsqu'elles sont imbriquées dans un tableau ou un objet. Bien que ce sur-ensemble soit cohérent avec la définition étendue du "texte JSON" dans la nouvelle RFC 7159 (qui remplace les RFC 4627) et ECMA-404 , cela peut entraîner des problèmes d’interopérabilité avec les anciens analyseurs JSON qui respectent strictement la RFC 4627 encoder une seule valeur scalaire.

Cela signifie que, par exemple, une chaîne simple sera considérée comme un objet JSON valide en PHP:

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

Sortie:

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

Mais les chaînes simples, pas dans un tableau ou un objet, ne font pas partie de la norme RFC 4627 . En conséquence, des vérificateurs en ligne tels que JSLint , JSON Formatter & Validator (en mode RFC 4627) vous donneront une erreur.

Il existe un troisième paramètre $depth pour la profondeur de la récursivité (la valeur par défaut est 512 ), ce qui signifie la quantité d'objets imbriqués à l'intérieur de l'objet d'origine à décoder.

Il y a un quatrième paramètre $options . Il n'accepte actuellement qu'une seule valeur, JSON_BIGINT_AS_STRING . Le comportement par défaut (qui omet cette option) est de convertir les grands entiers en flottants au lieu de chaînes.

Les variantes non majuscules non valides des littéraux true, false et null ne sont plus acceptées comme entrées valides.

Donc, cet exemple:

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());

Avant 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"

Et aprè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"

Un comportement similaire se produit pour false et null .

Notez que json_decode() renverra NULL si la chaîne ne peut pas être convertie.

$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 

Il n'est pas sûr de ne compter que sur la valeur de retour NULL pour détecter les erreurs. Par exemple, si la chaîne JSON ne contient rien d'autre que "null" , json_decode() renverra null , même si aucune erreur ne s'est produite.

Encodage d'une chaîne JSON

La fonction json_encode convertira un tableau PHP (ou, depuis PHP 5.4, un objet implémentant l'interface JsonSerializable ) en une chaîne codée JSON. Il retourne une chaîne codée JSON en cas de succès ou FALSE si une erreur survient.

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

Lors de l'encodage, les types de données PHP string, integer et boolean sont convertis en leur équivalent JSON. Les tableaux associatifs sont codés en tant qu'objets JSON et, lorsqu'ils sont appelés avec des arguments par défaut, les tableaux indexés sont codés en tant que tableaux JSON. (Sauf si les clés de tableau ne sont pas une séquence numérique continue commençant à 0, auquel cas le tableau sera codé en tant qu'objet JSON.)

echo json_encode($array);

Sortie:

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

Arguments

Depuis PHP 5.3, le second argument de json_encode est un masque de bits pouvant être un ou plusieurs des suivants.

Comme avec tout masque de bits, ils peuvent être combinés avec l'opérateur OU binaire | .

PHP 5.x 5.3

JSON_FORCE_OBJECT

Force la création d'un objet au lieu d'un tableau

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

Sortie:

["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

Assure les conversions suivantes lors de l'encodage:

Constant Contribution Sortie
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);

Sortie:

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

JSON_NUMERIC_CHECK

Garantit que les chaînes numériques sont converties en nombres entiers.

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

Sortie:

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

JSON_PRETTY_PRINT

Rend le JSON facilement lisible

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

Sortie:

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

JSON_UNESCAPED_SLASHES

Comprend non échappés / slashs dans la sortie

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

Sortie:

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

JSON_UNESCAPED_UNICODE

Inclut des caractères encodés en UTF8 dans la sortie au lieu de chaînes codées \u encodées

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

Sortie:

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

JSON_PARTIAL_OUTPUT_ON_ERROR

Permet au codage de continuer si des valeurs non codables sont rencontrées.

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

Sortie:

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

JSON_PRESERVE_ZERO_FRACTION

S'assure que les flottants sont toujours codés comme des flottants.

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

Sortie:

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

JSON_UNESCAPED_LINE_TERMINATORS

Utilisé avec JSON_UNESCAPED_UNICODE , revient au comportement des anciennes versions de PHP et n'échappe pas aux caractères U + 2028 LINE SEPARATOR et U + 2029 PARAGRAPH SEPARATOR. Bien que valide en JSON, ces caractères ne sont pas valides en JavaScript. Le comportement par défaut de JSON_UNESCAPED_UNICODE a JSON_UNESCAPED_UNICODE été modifié dans la version 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);

Sortie:

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

Débogage des erreurs JSON

Si json_encode ou json_decode pas la chaîne fournie, elle retournera false . PHP lui-même ne générera pas d'erreurs ou d'avertissements quand cela se produira , il incombe à l'utilisateur d'utiliser les fonctions json_last_error () et json_last_error_msg () pour vérifier si une erreur s'est produite et d'agir en conséquence (déboguer, afficher un message d'erreur) , etc.).

L'exemple suivant montre une erreur courante lors de l'utilisation de JSON, à savoir un échec de décodage / encodage d'une chaîne JSON (dû au passage d'une chaîne de caractères codée UTF-8 incorrecte, par exemple) .

// 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() renvoie un message lisible par l'homme de la dernière erreur survenue lors de la tentative d'encodage / décodage d'une chaîne.

  • Cette fonction retournera toujours une chaîne , même si aucune erreur ne s’est produite.
    La chaîne de non-erreur par défaut est No Error
  • Il renverra false si une autre erreur (inconnue) s'est produite
  • Attention lors de l’utilisation de ce type de boucles, json_last_error_msg sera remplacé à chaque itération.

Vous ne devez utiliser cette fonction que pour afficher le message et non pour le tester dans les instructions de contrôle.

// 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());
}

Cette fonction n'existe pas avant PHP 5.5. Voici une implémentation 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() renvoie un entier mappé à l'une des constantes prédéfinies fournies par PHP.

Constant Sens
JSON_ERROR_NONE Aucune erreur ne s'est produite
JSON_ERROR_DEPTH La profondeur maximale de la pile a été dépassée
JSON_ERROR_STATE_MISMATCH JSON invalide ou mal formé
JSON_ERROR_CTRL_CHAR Erreur de caractère de contrôle, éventuellement mal encodée
JSON_ERROR_SYNTAX Erreur de syntaxe (depuis PHP 5.3.3)
JSON_ERROR_UTF8 Caractères UTF-8 mal formés, éventuellement mal encodés (depuis PHP 5.5.0)
JSON_ERROR_RECURSION Une ou plusieurs références récursives dans la valeur à coder
JSON_ERROR_INF_OR_NAN Une ou plusieurs valeurs NAN ou INF dans la valeur à coder
JSON_ERROR_UNSUPPORTED_TYPE Une valeur d'un type qui ne peut pas être encodé a été donnée

Utilisation de JsonSerializable dans un objet

PHP 5.x 5.4

Lorsque vous créez des API REST, vous devrez peut-être réduire les informations d'un objet à transmettre à l'application cliente. À cette fin, cet exemple illustre l'utilisation de l'interface JsonSerialiazble .

Dans cet exemple, la classe User étend en fait un objet de modèle de base de données d'un ORM hypotétique.

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

Ajoutez l'implémentation JsonSerializable à la classe en fournissant la méthode jsonSerialize() .

public function jsonSerialize()

Maintenant, dans votre contrôleur d'application ou votre script, en passant l'objet User à json_encode() vous obtiendrez le tableau jsonSerialize() méthode jsonSerialize() au lieu de l'intégralité de l'objet.

json_encode($User);

Reviendra:

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

exemple de propriétés

Cela réduira à la fois la quantité de données renvoyée par un noeud final RESTful et permettra d'exclure les propriétés d'objet d'une représentation json.


Utilisation de propriétés privées et protégées avec json_encode()

Pour éviter d'utiliser JsonSerializable, il est également possible d'utiliser des propriétés privées ou protégées pour masquer les informations de classe à partir de la sortie json_encode() . Il n'est alors pas nécessaire que la classe implémente \ JsonSerializable.

La fonction json_encode () encode uniquement les propriétés publiques d'une classe 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));

Sortie:

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

En-tête json et la réponse renvoyée

En ajoutant un en-tête avec le type de contenu 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();

L'en-tête est là pour que votre application puisse détecter quelles données ont été renvoyées et comment elles doivent être traitées.
Notez que: l'en-tête de contenu n'est que des informations sur le type de données renvoyées.

Si vous utilisez UTF-8, vous pouvez utiliser:

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

Exemple 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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow