J'ai appris quelque chose à mes dépens aujourd'hui concernant la notation JSON (JavaScript Object Notation). Vous savez, le genre de situation où on se sent particulièrement imbécile parce qu'on avait la solution sous nos yeux ? Je m'explique.
J'avais l'habitude de représenter les objets sous la forme :
{ key : value }
Ce qui est 100% valide en JavaScript. Cependant, avec l'application web que je suis en train de développer, je devais dans certains cas récupérer l'output JSON à partir de PHP et le décoder à l'aide de la fonction json_decode(). Pour moi, c'était une première. Pourtant, au moment de la lecture, PHP ne reconnaissait rien. Une chaîne de caractère vide!
J'ai lu la documentation, juste au cas où que quelque chose m'ait échappé, et j'ai vu que la fonction prenait un deuxième argument optionnel, false par défaut, ce qui veut dire que le résultat est retourné sous la forme d'un objet.
# sous la forme d'un objet basé sur stdClassJ'ai essayé les deux formes, sans succès. Mais la solution s'est finalement présentée. Pour être décodée, la chaîne JSON doit être formatée avec le nom des clés entre guillemets :
# $obj = json_decode($json);
$obj = json_decode($json, false);
echo $obj->key;
# sous la forme d'un tableau associatif
$as = json_decode($json, true);
echo $as['key'];
{ "key" : value }
Voilà où était le bobo. La magie dans tout ça est que cette notation est valide autant côté client que serveur. Alors à l'avenir, je m'efforcerai de toujours l'écrire de cette façon.
Sur le même sujet, un autre truc que je peux partager avec vous suite à mon expérience concerne les valeurs booléennes. Faites attention comment vous la faites imprimer dans votre objet JSON. Au même titre que la déclaration suivante lance une erreur :
var bool = True;Le langage JavaScript accepte uniquement les valeurs true / false écrites en minuscules, même à l'intérieur d'un objet JSON :
// refuséAutrement, ça invalidera la totalité de l'objet et json_decode() ne pourra pas l'interpréter.
{ "inserted" : True }
// accepté
{ "inserted" : true }