Aller au menu - Aller au contenu

Stocker les sessions dans votre base de données

Pour accéder à cette section
Connectez-vous !
connexion_rpx
Page Précédente  1  2 
Pseudo Commentaire
Page Précédente  1  2 
Hors ligne mentos2000 # Posté le 25/03/2009 à 14:25:21

Bonjour, je suis pas très familier avec les variables de sessions et leur stockage.
Mais lorsqu'il existe plusieurs variable dans le tableau de session $_SESSION comment sont ils stockées en base de données ?

Example: Panier $_SESSION['fruit']='orange'; $_SESSION['legume']='epinard';

Est ce que cela marche avec la classe fournie ? ou peut on stocker qu'une seule donnée .
Hors ligne F_D_V # Posté le 25/03/2009 à 16:01:41

Études : INSA Rennes

Mentos2000 oui cela fonctionne et c'est justement tout l'intérêt de cette méthode l'utilisation des sessions est la même qu'avant! Il y a que l'endroit de stockage de celle-ci qui change tout le reste fonctionne pareil !
Hors ligne SoupeurStar # Posté le 04/04/2009 à 17:22:27
Avatar

EDIT: bon en gos on stock les information de session dans la BDD au lieu du serveur ... mais point de vue securiter ca change pas grand chose :-°

ya au moins autant de faille sur un dossier de session qu'il n'y en a sur une BDD

quoi que j'ai plus confience a un dossier proteger avec un bon vieux Deny From All
(la peur de l'injection SQL :lol: )

je met pas de note car, point de vue securiter, chuis pas sur qu'on y gagne vraimment...

*pas convaincu* :o

P.S: merci pour le "session_regenerate_id()" je connaissais pas
 
Hors ligne debo41 # Posté le 15/06/2009 à 16:01:31

Bonjour,
Je suis entrain d'utiliser cette technique de gestion des sessions et j'ai quelques probleme.
pour cloturer une session il faut mettre quoi comme code
Est ce que session_destroy(); suffit
Car c'est ce que je fais et ca ne me supprime jamais l'entré correspondante dans la base de données
Alors je pense que je dois mal faire

Merci d'avance pour votre aide
Hors ligne dondon # Posté le 04/08/2009 à 12:00:02

à propos de cette ligne de la fonction 'open' qui appelle gc :
$this->gc(); //on appelle la fonction gc

elle est inutile:
au démarrage d'une session, gc est automatiquement exécuté en fonction d'une probabilité déterminé par le ratio "session.gc_probability/session.gc_divisor" (variables défini dans php.ini). par défaut ce ratio est 1/100, soit 1 chance sur 100.

donc à la place d'un lancement inclus dans l'ouverture, il faut fixer ces 2 valeurs AVANT session_start :

ini_set( 'session.gc_probability', 5 );
ini_set( 'session.gc_divisor', 100 );

là on a 5/100 de chance que gc soit lancé


pour une exécution à chaque ouverture :

ini_set( 'session.gc_probability', 1 );
ini_set( 'session.gc_divisor', 1 );

là on a 1/1 de chance (100%) que gc soit lancé...
Hors ligne Nanocom # Posté le 26/10/2009 à 20:55:38
Avatar

Ville : Ittenheim
Pays : France métropolitaine
Études : INSA Lyon

L'idéal en fait serait d'utliser le moteur MEMORY de MySQL, pour stocker les sessions directement dans la RAM, ça accélère grandement l'accès à l'information, et si on perd la session à cause d'un crash du serveur c'est pas trop grave puisque l'utilisateur peut se reconnecter.

Donc en gros, il faut juste changer MyISAM par MEMORY, et tu optimises ton script en claquant des doigts !
Hors ligne rp0401 # Posté le 28/12/2009 à 13:56:27
Avatar

Citation
L'idéal en fait serait d'utiliser le moteur MEMORY de MySQL


Je préconise la même chose. C'est même très important en terme de performances selon moi.
Hors ligne hornetbzz # Posté le 02/02/2010 à 10:36:10
que la force soit avec toi
Avatar

Études : ESTACA

en PDO, ça aurait été encore plus sympa :D
Hors ligne bestsuan # Posté le 11/02/2010 à 21:05:29

Salut,on tiens tt dabord a remercier ce tuto pour son tutoriel .
Ma demande est posé a tt les membres qu on déja utiliser cette classe , comment l'utiliser ? donnez ns un exemple simple pour mieux comprendre ! et merci bien
Hors ligne bestsuan # Posté le 14/02/2010 à 00:15:11

Ou est le responsable de ce tutoriel! !!!!
Hors ligne Grabeuh # Posté le 17/02/2010 à 14:59:56
Je rale pas, je m'exprime !
Avatar

Avis : Très bon

Citation
Donc en gros, il faut juste changer MyISAM par MEMORY, et tu optimises ton script en claquant des doigts !

On utilise un champ de type TEXT pour le stockage des données sérialisées, vu qu'on ne connait pas leur taille à l'avance et qu'il y a de grandes chances que ces dernières dépassent 255 caractères et qu'on ne puisse donc pas les mettre dans un champ CHAR ou VARCHAR. Problème de taille : Citation : doc MySQL
MEMORY ne supporte pas les colonnes de type BLOB/TEXT.

L'idée est donc bonne mais tombe à l'eau à cause de restrictions techniques.

Quitte à vouloir accéder aux données rapidement, on passera alors par un gestionnaire de cache en RAM type memcache, APC ou XCache, qui ne posera pas cette restriction, sera tout aussi rapide voire plus car il évitera de passer par un interpreteur SQL, et ne posera pas énormément de soucis pour réécrire les fonctions de stockage, le principe reste le même, seul l'utilisation du SQL est retirée (EDIT : il faudra aussi rajouter un array stocké dans le cache pour garder une trace de la durée de vie des sessions) .

Par contre, quitte à laisse en base de données, il sera préférable de mettre le default charset en utf8, des fois qu'on voit un jour se pointer PHP6 en full unicode :D


PS :
@bestsuan :
en lisant les 2 premiers commentaires de cette page, tu aurais trouvé tout de suite...
Citation : F_D_V
c'est justement tout l'intérêt de cette méthode l'utilisation des sessions est la même qu'avant! Il y a que l'endroit de stockage de celle-ci qui change tout le reste fonctionne pareil !
Hors ligne Maz # Posté le 14/03/2010 à 14:56:19
Be quiet.
Avatar

Ville : La seyne-sur-mer
Pays : France métropolitaine

J'ai adapté ce système pour:
pdo avec postgresql
faire passer la connexion PDO en parametre plutot que de recréer une instance de connexion dans la class
pouvoir faire passer des objets dans le SGBD(ce qui n'était pas possible avec ta classe actuelle car tu ne sérialize pas les sessions)
appeler le ini_set('session.save_handler', 'user') et le session_set_save_handler() directement dans la class
enlever l'appel de gc() à chaque open()
utiliser un Delete/Insert plutôt que le count()/Insert/Update pour une raison d'optimisation puisque de toute manière, s'il existe, il sera remplacer.
Pour ceux que ça intéresses:
Secret (cliquez pour afficher)
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?php
	class Sessions {
		private $tempsExpiration = '12 hours';
		private $dbConnexion;
		
		public function __construct(PDO &$dbConnexion) {
			ini_set('session.save_handler', 'user');
			$this->dbConnexion = $dbConnexion;
			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();
		}
		
		public function open () {
			return TRUE;
		}
		
		public function read ($sid) {
			$donneesSelect = <<<SQL
				SELECT donnees
				FROM sessions
				WHERE id= '$sid';
SQL;
			$sqlRequete = $this->dbConnexion->query($donneesSelect)or die(print_r($this->dbConnexion->errorInfo()));	
			$sqlReponse = $sqlRequete->fetch(PDO::FETCH_ASSOC);
			
			if(!count($sqlReponse)) return FALSE;
			else return unserialize(stripslashes($sqlReponse['donnees']));
		}
		
		public function write ($sid, $donnees) {
			$donnees = $this->dbConnexion->quote(addslashes(serialize($donnees)));
			$idDeleteInsert = <<<SQL
				SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
				DELETE FROM sessions
				WHERE id = '$sid';
				INSERT INTO sessions(id, donnees, expiration)
				VALUES('$sid', $donnees, current_timestamp + interval '$this->tempsExpiration')
SQL;
			$this->dbConnexion->beginTransaction();
			$retour = $idDeleteInsert = $this->dbConnexion->exec($idDeleteInsert)or die(print_r($this->dbConnexion->errorInfo()));
			$this->dbConnexion->commit();
			return $retour;
		}
		
		public function close() {
			$this->dbConnexion = NULL;
		}
		
		public function destroy ($sid) {
			$sessionDelete = <<<SQL
				DELETE FROM sessions
				WHERE id = '$sid'
SQL;
			$retour = $this->dbConnexion->exec($sessionDelete);
			return $retour;
		}
		
		public function gc ()
		{
			$sessionsDelete = <<<SQL
				DELETE FROM sessions
				WHERE expiration < current_timestamp
SQL;
			$retour = $this->dbConnexion->exec($sessionsDelete);
			return $retour;
		}
		
	}
	$session = new Sessions($dbConnexion);
?>

La table utilisé contient les champs:
Code : Autre
1
2
3
id                   character varying(40)
donnees              text
expiration timestamp with time zone


Si y'a des questions, par MP car je ne suit pas spécialement les commentaires des tutos.

eMazine.fr - Mon site perso.
 
Hors ligne F_D_V # Posté le 17/03/2010 à 19:24:33

Études : INSA Rennes

Comme vous l'avez peut être remarqué par le manque de mise à jour ,je n'ai malheureusement plus le temps de m'occuper de ce tuto à cause de mes études. Si quelqu'un veux le reprendre qu'il me contact par mp...
Hors ligne SmallFitz # Posté le 16/05/2010 à 17:59:03

Études : BTS IRIS

Au vu des premiers commentaires, qui remettent en question le gain de sécurité, et l'absence de réponse de l'auteur à ces commentaires, je reste un Zéro sceptique.
J'attendrais donc la venue d'explications plus convaincantes avant de me lancer.
Hors ligne The Art-Breaker # Posté le 21/06/2010 à 17:27:40
Life is a rock'n roll song

bonjour, tout d'abord, un pti mot pour dire que ce tuto est nickel, c'est pile poil ce qu'il me faut pour regler un probleme de session que je connais actuellement ^^
Toutefois, j'aimerais juste avoir un eclaircissement sur cette solution: j'aimerais en fait savoir si celui ci doit se mettre sur chaque page du code (vu que le navigateur remet les valeurs de session par defaut à chaque changement de page) ou uniquement lors de la connexion d'un utilisateur?
Merci d'avance pour ce petit eclaircissement
PS: en lisant le code, je me suis apercu que le nom de la table créee ("SESSION") ne correspond pas a la table appelée ("sess_table") petite faute sans gravité bien sur mais peut etre embarassante pour les novices :D

hate, tears, scars and pain... life
 
Hors ligne berli888 # Posté le 23/07/2010 à 10:03:51
Celsius Online
Avatar

Ville : Noisiel
Pays : France métropolitaine
Études : SUPINFO Île-de-France à Paris

Les données $_SESSION ont beau être stockés sur le serveur, il est toujours possible d'y accéder avec l'usurpation d'identifiants de sessions qui peuvent être stockés dans un cookie ou bien transmis de page en page grâce à l'url.
Il faut donc éviter de stocker des données sensibles dans les sessions comme le rang du visiteur en clair (admin, modérateur, membre) ou même ne pas le faire du tout.

Image utilisateur
 
Hors ligne Limuna # Posté le 21/07/2011 à 13:58:49
Avatar

Avis : Bon

Salut à tous.
J'ai découvert les Callbacks par ce tuto, mais j'ai beaucoup de mal à appréhender cette bête. J'ai compris ce que c'est mais pas l'utilisation et sur le fofo, malgré les réponses des experts, je n'ai pas réussi à percer le mystère.
Quelqu'un pourrait-il m'indiquer un cours sur ces bêtes-là ou se dévouer pour m'expliquer plus en détail ? J'ai notemment remarqué 2 manière d'appeler les fonctions dans le cours et on m'en a donné encore d'autres sur le fofo, je reste perplexe...
 
Hors ligne Exgal # Posté le 09/02/2012 à 10:29:02

Hello tout le monde,

Bien que le post soit assez vieux, je viens tout de même proposer quelques optimisations de requêtes SQL (uniquement) pour tous ceux qui lieront ce tuto et ce commentaire.

En ce qui concerne la fonction read, tous les éléments cités ci-dessous peuvent être remplacés.
Code : Autre
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$sql = "SELECT COUNT(sess_id) AS total
                FROM ".SESS_TABLE."
                WHERE sess_id = '$sid' ";
                
        $query = mysql_query($sql,$connect) or exit(mysql_error());
        $return = mysql_fetch_array($query);
        if($return['total'] == 0)//si la session n'existe pas encore
        {
                $sql = "INSERT INTO ".SESS_TABLE."
                        VALUES('$sid','$data','$expire')";//alors on la crée
        }
        else//sinon
        {
                $sql = "UPDATE ".SESS_TABLE." 
                        SET sess_datas = '$data',
                        sess_expire = '$expire'
                        WHERE sess_id = '$sid' ";//on la modifie
        }                
        $query = mysql_query($sql,$this->connect) or exit(mysql_error());


par ceci:
Code : Autre
1
2
3
4
5
6
7
$sql = "INSERT INTO `sess_table` (`sess_id`,`sess_datas`,`sess_expire`)
        VALUES ('$sess_id','$sess_datas','$sess_expire') 
        ON DUPLICATE KEY UPDATE 
        `sess_datas`=VALUES(`sess_datas`), 
        `sess_expire`=VALUES(`sess_expire`)";
                
        $query = mysql_query($sql,$connect) or exit(mysql_error());


Beaucoup plus lisible et performant à l'exécution.
Mais aussi bien plus rapide et portable qu'un REPLACE. ;)

Dans les requêtes du type SELECT pour sélectionner l'id de la session je recommande aussi de mettre un "LIMIT 1" tout à la fin de la requête.

En effet, vous n'avez besoin que d'une session et il faut savoir que même lorsque mysql trouve votre résultat, il continue de parcourir la table, avec "LIMIT 1" il s'arrête dès le premier résultat trouvé.
Pour accéder à cette section
Connectez-vous !
connexion_rpx