Php5 - classe de gestion de session

Soyez le premier à donner votre avis sur cette source.

Snippet vu 29 097 fois - Téléchargée 25 fois


Contenu du snippet

Huhu, bon ca faisait longtemps que j'avais pas posté un ptit code alors voila :)

Déja, avec un titre aussi compliqué (quoi que), je vais essayer de m'exprimer en bon français.
Tout le monde connait les sessions. On commence par appeler session_start(), et on utilise $_SESSION[] par la suite.
Petit rappel de fonctionnement, les données de sessions sont stockées sur le disque dur du serveur dans un fichier pour chaque visiteur.

Cependant, pour une envie comme une autre on désire utiliser un système de base de donnée au lieu d'un système via fichier. On pourrait écrire une classe qui fasse ca avec un parsing comme je l'avais fait il y a bien longtemps (que je n'ai jamais fini). Cependant, le procédé est bien trop lourd.

Comment faire pour mixer performance d'une base de donnée avec la performance des sessions sans tout ré-écrire ? Via session_set_save_handler().
Il suffit de recréer les méthodes dont on a besoin pour les faires intéragir avec une base de donnée plutôt qu'avec un système de fichier.
Et grâce à tout ca, on peut utiliser session_start, $_SESSION[] et toutes les fonctions session_*.

Pour pouvoir utiliser correctement l'approche objet de PHP5, j'ai découpé ce projet en 2.
La première partie est une classe abstraite. Toute classe de session DOIT être dérivée de cette classe abstraite. Elle contient les méthodes nécessaires au bon fonctionnement des sessions. (ainsi que les propriétés utiles pour chaque classe dérivée).
La deuxième partie est une classe concrète. Ici, j'ai choisi de faire une classe concrète de base de donnée. Je reprend donc les méthodes abstraites pour les compléter comme prévu.

On peut utiliser n'importe quel système pour les sessions, que ce soit un gestionnaire LDAP, une base de donnée SQL, nu système de fichier bref... il suffit pour cela de dériver la classe abstraite et de remplir les méthodes.

Voici donc ce que ca donne.

Source / Exemple :


<?php
abstract class SessionManager {

 public $session_name;
 public $lifeTime = 3600;

 public $id;
 
 abstract public function open($savePath, $sessName);
 abstract public function close();
 abstract public function read($sessID);
 abstract public function write($sessID,$sessData);
 abstract public function destroy($sessID);
 abstract public function gc($sessMaxLifeTime);	

 public function __construct() {
 	
  if ( !session_set_save_handler(array(&$this,'open'),
                                 array(&$this,'close'),
                           		 array(&$this,'read'),
                          		 array(&$this,'write'),
                          		 array(&$this,'destroy'),
                          		 array(&$this,'gc') ) ) {
       throw new Exception('Erreur lors de l\'init des sessions !');
  }

  session_start();
 	
 }
}

class SQLSessionManager extends SessionManager {

 private $db;
 
 public function __destruct() {
 	session_write_close();
 }
 
 public function open($savePath, $sessName) {
 	
  $this->db = mysql::GetInstance();	
  return true;
 	
 }

 public function close() {
 	
  $this->gc(ini_get('session.gc_maxlifetime'));
  unset($this->db);
  
 }

 public function read($sessID) {
 	
  $this->id = $sessID;
  $this->db->prepare("SELECT data FROM session WHERE id = '{1}' AND expires > {2}",
                     $sessID, time() );
  $this->db->query();

  return ( ( $row = $this->db->fetch_row() ) !== FALSE ) ? $row[0] : ' ';
	
 }
 
 public function write($sessID,$sessData) {

  $this->id = $sessID;
  $newExp = time() + $this->lifeTime;
  $this->db->prepare("INSERT INTO session (id, data, expires) VALUES ('{1}', '{2}', {3})
                      ON DUPLICATE KEY UPDATE data = '{2}', expires = {3}",
   	                  $sessID, $sessData, $newExp);
  $this->db->query();
  
  return TRUE;
 	
 }
 
 public function destroy($sessID) {

  $this->db->prepare("DELETE FROM session WHERE id = '{1}'", $sessID);
  $this->db->query();
  return ( $this->db->affected_rows() === 1 ) ? TRUE : FALSE;
  	
 }
 
 public function gc($sessMaxLifeTime) {

  $this->db->prepare("DELETE FROM session WHERE ( UNIX_TIMESTAMP(expires) - UNIX_TIMESTAMP(NOW()) ) > '{1}' ", $sessMaxLifeTime);
  $this->db->query();
  return $this->db->affected_rows();
 	
 }
 
}
?>

Conclusion :


Et voila. Un gros merci à la doc de PHP la dessus sur lequel j'ai pris exemple.
Je compte rajouter de nouveaux trucs, mais la base est la en tout cas.
Si ca peut aider quelqu'un tant mieux :)

J'ai oublié, mes méthodes de singletons peuvent se retrouver dans la classe abstraite ca ne posera aucun problème :)

A voir également

Ajouter un commentaire Commentaires
Messages postés
217
Date d'inscription
mercredi 26 juillet 2006
Statut
Membre
Dernière intervention
16 août 2018

Oui SMAHANEAAI (tu parles d'un pseudo !!! )
pour moi aussi un petit exemple de "mise enpratique" aurait été utile pour ce tuto !
Car c'est bel et bien un tuto, vu tous les trucs à apprendre dedans !!!
Messages postés
68
Date d'inscription
jeudi 27 janvier 2011
Statut
Membre
Dernière intervention
7 février 2014
10
merci bcp pr le code qui est sans aucun doute très utile, mais bon je suis débutante avec php5 et c'est la premiere fois que je désir l'utiliser dans la création des Sessions et je n'ai pas tout à fait compris comment faire appelle à ces méthodes de cette class!! par exemple je n'ai pas compris c'est quoi le paramètre "savePath" ? et puis pour "$session_name" faut il par exemple au début du code de la page dont on utilise la session faire son initiation (le fait de la nommé) ??

un petit exemple peut être utile pour moi :D
et merci d'avance!
Messages postés
1293
Date d'inscription
mardi 9 novembre 2004
Statut
Membre
Dernière intervention
21 mai 2015

"en gros tu veux limiter le nombre de visiteurs à ton site... et il fait quoi le 11 eme internaute qui veut se connecter à ton site. " > 10 sessions / IP simultané (ip+hots), pour eviter que la db ne souffre par flood (ex: je m'identifit, je me reidentifit, 1000 fois de suite etc...), donc generer autemps de sessions inutiles.
IP+Host, pour la simple et bonne raison: une ip peut etre reatribuer, mais l'host lui theoriquement ne sera pas le meme, exemple: une IP Wanadoo, l'ip je la rajoute pour avoir quelque chose en cas où l'host n'est plus valide: une IP Wanadoo.
10 sessions/Ip : Imagine un sous reseau avec 3 pc une meme IP publique connecté à ton site, si ils perdent leurs id de session, ils vont devoir la reecrer, mais il leurs restera encore quelques essaies. Tout cela pour eviter de mettre en danger MySQL.


Oui parce que toi tu te base sur l'ip... mais dans le cas d'une session classique comme c'est le cas ici l'ip on s'en fout... .. .

Et si tu ne comprend pas pourqoui il faut effacer toutes les sessions expirer (je parle des sessions coté db), c'est tout simple: tout le monde ne clique pas sur "Deconnexion".


C'est toi qui ne doit pas avoir compris ce que je voulais dire... tu crois qu'entre le moment ou je tape ce message et le moment ou je vais le soumettre il y en aura beaucoups des sessions expirées... alors imagine sur un site à petit traffic... faire un gc à chaque instanciation de la class ça veut dire une requete de plus à chaque chargement de page (voir plus si tu fais pas de l'instanciation unique) c'est totalement inutile... si tu regarde le systeme de session par défaut le garbage collection se déclenche en moyenne toute les 100 éxécutions (1% de probabilité de déclenchement)... c'est quoi le mieux... déclencher le gc à chaque instanciation pour virer 3 pauvres sessions expirées ou le déclencher toute les 30 minutes pour en virer 50 en un coups... .. .

et hop...



Pour la forme... .. . ;o)

^_^

@ tchaOo°
Messages postés
947
Date d'inscription
mercredi 19 novembre 2003
Statut
Membre
Dernière intervention
5 avril 2008
3
Kankrelune > "mais que tu réécris les url avec l'id de session... .. ." > j'ai dut mal m'exprimer, j'utilise l'id de sessions maison , j'utilise pas les $_SESSION, justement.


"en gros tu veux limiter le nombre de visiteurs à ton site... et il fait quoi le 11 eme internaute qui veut se connecter à ton site. " > 10 sessions / IP simultané (ip+hots), pour eviter que la db ne souffre par flood (ex: je m'identifit, je me reidentifit, 1000 fois de suite etc...), donc generer autemps de sessions inutiles.
IP+Host, pour la simple et bonne raison: une ip peut etre reatribuer, mais l'host lui theoriquement ne sera pas le meme, exemple: une IP Wanadoo, l'ip je la rajoute pour avoir quelque chose en cas où l'host n'est plus valide: une IP Wanadoo.
10 sessions/Ip : Imagine un sous reseau avec 3 pc une meme IP publique connecté à ton site, si ils perdent leurs id de session, ils vont devoir la reecrer, mais il leurs restera encore quelques essaies. Tout cela pour eviter de mettre en danger MySQL.

Et à ce que je sache, ont a pas tous la meme IP..


Et si tu ne comprend pas pourqoui il faut effacer toutes les sessions expirer (je parle des sessions coté db), c'est tout simple: tout le monde ne clique pas sur "Deconnexion".

Kankrelune, as-tu une autre <quote></quote> pour la route?
Messages postés
2350
Date d'inscription
mercredi 13 octobre 2004
Statut
Membre
Dernière intervention
18 avril 2015
3
Ah oui, tel quel le système est bien plus lent à cause des requètes. Je comptais justement utiliser ce système pour une gestion de stats derrière un peu plus tard.

Mais ce soir je m'y attèle :)
Afficher les 17 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.