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 |
.
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"}
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]
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"}
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"}
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]
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 estNo 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
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);
});