Utilisation Json comme base de données
(Cet article a été écrit il y a très longtemps, dans une galaxie très très lointaine, par un nakama inconnu)
Aujourd’hui on va voir comment utiliser le Json comme base de données. L’avantage est de ne plus avoir besoin de MySQL.
Cette solution peut être intéressante pour de petits sites qui ne demandent pas trop d’administration.
Cet article va montrer comment utiliser le format Json et quelques points intéressants comme par exemple mettre en place une Api qui va stocker dans un fichier Json des utilisateurs.
Ce qu’il faut garder en tête ici, c’est que chaque fichier Json peut être comparé à une table d’une base de données.
Contents
Variables et constructeur
class UserJson { private $id; private $data; private $table; private $table_id; private $user; private $users; public function __construct(){ $this->table = "users.json"; $this->table_id = "users_id.txt"; // si le fichier n'existe pas, on le crée if(!file_exists($this->table)){ $this->createTable(); } }
- ise en place des variables
- le constructeur va renseigner quelques informations : le nom du fichier Json et txt.
- on termine en vérifiant si les fichiers n’existent pas déjà, si ce n’est pas le cas on fera appel à la méthode qui les créera.
Les méthodes
// création des fichiers Json et txt // le fichier txt servira uniquement à l'incrémentation public function createTable(){ $handle = @fopen($this->table, "a+"); $handle_id = @fopen($this->table_id, "a+"); if($handle && $handle_id) { fclose($handle); fclose($handle_id); return true; } }
// Ajout d'un nouvel utilisateur public function addUser($data){ // info sur le nouvel user $this->data = $data; // on récupère le nouvel ID $this->id = $this->getId(); if( $this->id !== null ){ // on ajoute l'ID au nouvel user $this->data = array('id'=>$this->id) + $this->data; // on ajoute le nouvel user au fichier $file = @fopen($this->table, 'a+'); fputs($file, json_encode($this->data).','); fclose($file); return true; }else{ return "Erreur pour l'ajout de l'utilisateur."; } }
- a méthode getId() récupère un nouvel identifiant qui est contenu dans le fichier txt
- ligne 10 : on teste bien que le résultat n’est pas null sinon c’est qu’il y a eu un problème lors de la création de l’identifiant
- chaque utilisateur est sauvegardé sous cette forme : {« id »:31, »pseudo »: »Iron Man », »date »:1387821811},
// on récupère un nouvel ID private function getId(){ if( $txt = @fopen($this->table_id, "r+") ){ $this->id = fgets( $txt ); // récupération de la valeur $this->id = intval( $this->id ); // on vérifie qu’il s’agit bien d’un nombre $this->id++; // on incrémente fseek( $txt, 0 ); // réinitialisation du curseur fputs( $txt, $this->id ); // on écrit le nouveau nombre fclose($txt); return $this->id; }else{ return null; } }
Une simple méthode pour récupérer la valeur qui se trouve dans le fichier, l’incrémenter et ensuite sauvegarder la nouvelle valeur. J’ai repris la méthode du site openclassrooms pour compter le nombre de téléchargement.
Ici l’élément important : c’est que la méthode est en private, cela signifie qu’on va pouvoir y faire appel uniquement à l’intérieur de la class. Du coup on est certain qu’elle ne peut pas être appelé de l’extérieur, donc un identifiant sera créé uniquement quand on l’appellera dans la class elle-même.
// on récupère un user spécifique public function getUser($id){ // l'id de l'user qu'on souhaite récupérer $this->id = $id; // liste de tous les users $datas = $this->getAllUser(); // on teste si l'id correspond, si oui on renvoie le résultat foreach ($datas as $key => $row) { if($row->id == $id ) return $row; } // sinon return 'Aucun utilisateur ne correspond.'; }
// liste de tous les users public function getAllUser(){ // Si les users sont déjà définis if (isset($this->users)) return $this->users; // on récupère le contenu du fichier $contents = file_get_contents($this->table); $this->users = json_decode("[". substr($contents, 0, -1)."]"); // on renvoi le tableau des users return $this->users; }
- ligne 5 : elle permet de renvoyer directement tous les utilisateurs si la variable est déjà définie. Cela évite de faire plusieurs fois le travail si on appelle cette méthode plusieurs fois dans un même object
- on récupère le contenu encoder en Json, que l’on va décoder pour pouvoir l’utiliser
Cependant, les données sont sauvegardées de cette manière :
{"id":31,"pseudo":"Iron","date":1387821811},{"id":32,"pseudo":"Iron","date":1387821811},{"id":33,"pseudo":"Iron","date":1387821811},
Et pour pouvoir décoder le format Json les données doivent être comme cela :
[{"id":31,"pseudo":"Iron","date":1387821811},{"id":31,"pseudo":"Iron","date":1387821811},{"id":31,"pseudo":"Iron","date":1387821811}]
C’est pour cela que j’ajoute les [ ] et que je supprime la dernière virgule (ligne 9).
Il est tout à fait possible de faire autrement, enregistrer directement le tableau des utilisateurs, du coup on aura tout de suite la bonne syntaxe. Cependant, pour chaque ajout il faudrait tout récupérer et ré-écrire à chaque fois … perso je préfère écrire uniquement le nouvel utilisateur
// modification d'un utilisateur public function updateUser($id, $data){ $this->id = $id; $this->data = $data; // liste de tous les users $this->users = $this->getAllUser(); // on ouvre et on vide le fichier if($handle = @fopen($this->table, "w+")) { $this->data = ""; foreach ($this->users as $key => $row) { // si l'id correspond // on modifie le nouveau pseudo par exemple if( $row->id == $this->id ){ if($data['pseudo'] != "") $row->pseudo = $data['pseudo']; } $this->data .= json_encode($row).','; } // on ajoute tous les utilisateurs dans le fichier fputs($handle, $this->data); fclose($handle); return true; } }
// suppression d'un utilisateur public function removeUser($id){ $this->id = $id; // liste tous les users $this->users = $this->getAllUser(); if($handle = @fopen($this->table, "w+")) { $this->data = ""; foreach ($this->users as $key => $row) { if($row->id == $this->id ) unset($this->users[$key]); else $this->data .= json_encode($row).','; } fputs($handle, $this->data); fclose($handle); return true; } }
La suppression se passe plus ou moins comme la modification, on regarde si l’id correspond, si oui on le supprime du tableau des utilisateurs et ensuite on ré-écrit le tout dans le fichier.
On n’oublie pas la dernière accolade de la class
}
C’est fini
La class permet de créer, de modifier, de supprimer et de lister tous les utilisateurs. Évidemment, elle peut être améliorée ici je propose uniquement une base comme exemple
Mais il ne manque rien ?
Il manque peut-être les appels à la class enfin la création de l’object.
// initialisation $json = new UserJson(); // liste de tous les utilisateurs print_r( $json->getAllUser() ); // appel d'un utilisateur spécifique print_r( $json->getUser(31) ); // ajout d'un nouvel utilisateur $user = array('pseudo' => 'Batman', 'date'=>time()); var_dump( $json->addUser($user) ); // modification d'un utilisateur $update = array('pseudo'=>'Thor'); var_dump( $json->updateUser(44, $update) ); // suppression d'un utilisateur print_r( $json->removeUser(42) );
Idées d’amélioration ?
- Pseudo et email unique
- Rajouter des champs : mdp, email, date de modification etc.
- Mettre en place une 2e table pour classer les utilisateurs par catégories
- Mettre en place un système d’identification (login/mdp)
- etc.