JSON

JSON est une NOTATION d'objets, de tableaux et de valeurs nommées simples. Ces types sont imbriqués. Cela veut dire qu'on peut noter des tableaux d'objets, des objets de tableaux ou même des tableaux d'objets de tableaux de tableaux ! commençons par les types simples.

JSON permet de noter des valeurs nommées  simples

{
  "nom" : 'fred',
  "age" : 47,
  "masculin" : true
}

Dans JSON il y a forcément un container global (les accolades ci-dessus). L'objet global n'a pas de nom mais il a trois champs qui ont chacun un nom et une valeur. JSON peut également servir comme notation de tableaux.

[10, 2, 5, 'fred',  34, '12']

Les tableau ne sont pas forcément uniformes puisqu'ils peuvent contenir des choses différentes (ci-dessus nombres et chaînes de caractère).

ATTENTION : JSON peut emboîter les types donc dans le tableau nous pouvons rajouter un objet en plus des  nombres et des chaînes de caractère

[10, 2, 5, 'fred',  34, '12', {  "nom" : 'fred',"age" : 51}]

Ici l'objet n'a pas de nom il est juste posé à l'indice 6 du tableau. Par ailleurs la notation JSON est sur une ligne mais elle est tout aussi valide sur plusieurs lignes :

[
  10, 
  2, 
  5,  
  'fred',  
  34, 
  '12',
  {  
    "nom" : 'fred',
    "age" : 51
  }
]

On pourrait faire quasiment la même chose avec un objet mais il faudrait nommer chaque attribut 

{
  "att1": 10, 
  "att1":2, 
  "att2":5, 
  "nom":'fred',  
  "att3":34, 
  "att4":'12',
  '"id" : {  
    "nom" : 'fred',
    "age" : 45
  }
}

ICI on voit que l'attribut "nom" apparaît deux fois MAIS à des niveaux différents. Il ne peut pas apparaître deux fois au même niveau : 

{
  "nom" : 'fred',
  "age" : 51,
  "nom" : 'Vernier'
}
C'est interdit ... mais au fait comment on peut interdire ? JSON n'est pas compilé, il n'y a donc pas de compilateur qui me fera un "syntax error" ! JSON est une notation c'est donc du texte. Il peut être dans un fichier monobjet.txt ou monobjet.json, il peut aussi apparaître dans une chaîne de caractères :

let ch ="[10, 2, 5, 'fred',  34, '12', {'nom': 'fred','age': 45}]"; // en javascript

ou 

$ch =  "[10, 2, 5, 'fred',  34, '12', {  'nom' : 'fred','age' : 45}]"; // en PHP

ou enfin (et surtout !) il peut s'agir de texte qui transite sur le réseau Internet ! Bien sûr les lettres JS de JSON signifient Javascript mais cette notation étant très générale elle s'étend à pratiquement tous les langages de programmation.  L'intérêt de JSON se situe donc dans la communication et particulièrement dans la communication entre des langages différents (ie Javascript et PHP) mais aussi à la communication entre serveur et client (donc le modèle du web). 

Une mauvaise syntaxe de votre JSON pourra entraîner des problèmes lorsque vous tenterez de manipuler le json avec des fonctions 

{
  "activity_name":"RUGBY",
  "activity_code":"1",
  "activity_name":"FOOTBALL"
}
<?php
  $jsonString = file_get_contents('jsonFile.json');
  $data = json_decode($jsonString, true);
  $data['activity_name'] = "TENNIS";
  $newJsonString = json_encode($data, JSON_PRETTY_PRINT);
  file_put_contents('jsonFile2.json', $newJsonString);
?>
{
  "activity_name":"TENNIS",
  "activity_code":"1"
}
Attention je rappelle ici le code PHP pour ouvrir, modifier et resauver le JSON modifié mais il ne faut pas oublier le true dans json_decode(... ,true) qui créé un tableau associatif et il vaut mieux ne pas oublier le JSON_PRETTY_PRINT dans json_encode() pour garder un fichier lisible

Toutefois si un autre script php tente d'accéder au même fichier JSON quasiment en même temps que (entre le file_get_content() et le file_put_content()


alors le fichier peut se retrouvé corrompu. Pour éviter ce problème d'accès à une ressource partagée on pourra utiliser les 
fonctions de base des fichier (fopen, fread, fwrite)  avec un appel à flock() en plus

<?php
  $f = fopen('toto.json', 'r+');
  if (!flock($f, LOCK_EX))
     http_response_code(409); // conflict
  $jsonString = fread($f, filesize('games/'.$game.'.json'));
  $data = json_decode($jsonString, true); 
  // ICI ON MODIFIE LE CONTENU COMME UN TABLEAU ASSOCIATIF
  $newJsonString = json_encode($data, JSON_PRETTY_PRINT);
  ftruncate($f, 0);
  fseek($f,0);
  fwrite($f, $newJsonString);
  flock($f, LOCK_UN);
  fclose($f);
?>
C'est beaucoup plus verbeux mais ça marche !

            
DERNIERE MISE EN GARDE :
JSON utilise normalement des doubles quotes (") mais dans de nombreux langages on peut utiliser aussi de simples quotes('). C'est très pratique quand on veut écrire du JSON dans une chaine de caractères d'un langage car ça évite d' "escaper" le caractère " en écrivant : 
    let ch ="[10, 2, 5, \"fred\",  34, \"12\", {\"nom\": \"fred\", \"age\": 45}]"; // en javascript
Mais sachant que JSON préfère quand même le " (et que un ' peut tout faire planter sans rien dire) et que javascript tolère les deux on aurait pu préférer la troisième solution
    let ch1 ="[10, 2, 5, 'fred',  34, '12', {'nom': 'fred','age': 45}]"; // en javascript
    let ch2 ="[10, 2, 5, \"fred\",  34, \"12\", {\"nom\": \"fred\", \"age\": 45}]"; // en javascript
    let ch3 ='[10, 2, 5, "fred",  34, "12", {"nom": "fred", "age": 45}]'; // en javascript

Pour PHP c'est un peu plus subtil, PHP aussi autorise les " et les ' pour les chaînes de caractères mais elles fonctionnent un peu différemment (le double quote permet par exemple de mettre une variable dans le texte qui est remplacée par sa valeur)

Enfin je termine cette leçon sur JSON avec un exemple un peu plus conséquent en javascript qui transforme du texte en JSON (et vice-versa) et qui affiche les deux dans la console pour que vous compreniez mieux la différence 
    let ch ='[10, 2, 5, "fred",  34, "12", {"nom": "fred", "age": 45}]'; // en javascript
    console.log(ch);
    let js = JSON.parse(ch);
    console.log(js);
    js[6].nom = "frederic";
    let newch = JSON.stringify(js)
    console.log(newch);

console JS