OVH Cloud OVH Cloud

Modifier une session a partir de son id

17 réponses
Avatar
Julien Arlandis
Bonjour,

Connaissez vous un moyen d'accéder aux variables de session de n'importe
quel utilisateur à partir de son id de session (session_id()) ?

7 réponses

1 2
Avatar
Mickael Wolff
On 12/01/11 16:48, Julien Arlandis wrote:

... et à une connexion donnée.


C'est ce que j'entendais par application, je me suis mal exprimé, désolé.

Par exemple, si on veut partager une
donnée propre à l'application (comme le nombre de visiteurs) il ne me
semble pas que l'on puisse utiliser l'objet $_SESSION dans ce cas,
quelle serait la solution appropriée dans ce cas?


Ça dépend si on veut quelque chose de fiable ou non.

Par exemple si on veut afficher le prénom de l'utilisateur sur chaque
page du site, une solution serait de stocker le prénom en session à
chaque authentification de l'utilisateur. Dans ce cas l'appel à la base
de données ne se fait qu'une seule fois : lors de l'authentification.


La session n'est pas le bon endroit pour cacher les informations. Si
tu as besoin d'un cache, il faut utiliser un outil comme memcache. La
session est associée à un cookie. Si tu modifie une information qui est
cachée dans la session du même utilisateur, il faut penser à invalider
cette donnée. C'est un des cas d'utilisation où tu veux d'ailleurs
accéder à une autre donnée. Utiliser un vrai système de cache, c'est
pouvoir simplement invalider le cache lorsqu'on met à jour une donnée en
base. Ceci dit, cacher les données en session est tellement répandu
(ainsi que les bogues associés), que je ne peux te jeter la pierre.
Maintenant, utiliser un cache doit avoir une justification. La
première raison est que les caches sont souvent à l'origine de bogues
étranges. La seconde, c'est que l'usage d'un cache peut dégrader les
performances. La mise en place de caches devrait toujours être étudiée.
Comme toute optimisation.


Quand PHP et Mysql sont sur le même serveur,


Je tiens à préciser que, si tu as des problèmes de performance, la
première des choses est de séparer le serveur web du serveur de base de
données. À ce moment là, la question ne se pose pas. Si tu n'as pas de
problèmes de performance, tu peux éventuellement utiliser les sockets
unix pour des raisons de sécurité (supprimer une application réseau sur
la pile IP).
Avatar
Julien Arlandis
Le 12/01/2011 07:07, Mickael Wolff a écrit :

La session n'est pas un système de cache.
C'est un détournement du mécanisme standard des sessions. Une session
est l'ensemble des données relatives à l'état de ton application.



Je viens de lire qu'en JSP il existait des sessions globales, ça
s'appele des portées "application". Il se trouve que de tels objets me
seraient bien utiles en php, avez vous une idée comment implémenter
correctement de tels objets qui seraient accessibles en lecture et en
écriture par tous mes scripts? C'est quand même étonnant qu'il n'y ait
pas un tableau prévu à cet effet genre $_APPLICATION.
Avatar
Mickael Wolff
On 14/01/11 14:40, Julien Arlandis wrote:

Je viens de lire qu'en JSP il existait des sessions globales, ça
s'appele des portées "application". Il se trouve que de tels objets me
seraient bien utiles en php,


Dans quel cas ? Et qui s'occupe de mettre à jour ?

avez vous une idée comment implémenter
correctement de tels objets qui seraient accessibles en lecture et en
écriture par tous mes scripts?


Tu peux utiliser une base de données.

C'est quand même étonnant qu'il n'y ait
pas un tableau prévu à cet effet genre $_APPLICATION.


Non, ce n'est pas étonnant. PHP est basé sur un modèle d'exécution
éphémère. À chaque requête, l'application repart de zéro contrairement à
JSP qui est chargé en continue quand on utilise les servlets (tout du
moins avec Tomcat).
Avatar
Julien Arlandis
Le 14/01/2011 15:40, Mickael Wolff a écrit :

Par exemple, si on veut partager une
donnée propre à l'application (comme le nombre de visiteurs) il ne me
semble pas que l'on puisse utiliser l'objet $_SESSION dans ce cas,
quelle serait la solution appropriée dans ce cas?


Ça dépend si on veut quelque chose de fiable ou non.

Par exemple si on veut afficher le prénom de l'utilisateur sur chaque
page du site, une solution serait de stocker le prénom en session à
chaque authentification de l'utilisateur. Dans ce cas l'appel à la base
de données ne se fait qu'une seule fois : lors de l'authentification.


La session n'est pas le bon endroit pour cacher les informations. Si tu
as besoin d'un cache, il faut utiliser un outil comme memcache.



J'ai testé memcached et réalisé quelques tests :

<?php
$mem = new Memcache;
$mem->connect('localhost', 11211);

$_SESSION['toto'] = 1;
$mem->set('toto',1);

function get_session($champ)
{
global $mem;
return $mem->get($champ);
}

function get_memcached($champ)
{
return $_SESSION[$champ];
}

$ms = microtime(true);
for($i=0;$i<100000;$i++)
{
$toto = get_session('toto');
}
echo (int)((microtime(true) - $ms) * 1000) . " ms <br/>";

$ms = microtime(true);
for($i=0;$i<100000;$i++)
{
$toto = get_memcached('toto');
}
echo (int)((microtime(true) - $ms) * 1000) . " ms <br/>";
?>

retourne :

3800 ms (pour memcached)
44 ms (pour les sessions)

L'accès aux données avec les sessions est presque 100 fois plus rapide
qu'avec memcached. Et si j'utilise les sockets unix avec memcached je
passe de 3800 ms à 2800 ms. Bien sûr cela ne signifie pas que memcached
est plus gourmand en ressource que la serialisation, mais les temps de
réponse du fait de l'utilisation des sockets sont nettement plus
importants. Que faut il privilégier, le temps de réponse du script php,
l'utilisation du processeur, la consommation mémoire? Pour information,
je suis en train de coder un site qui a vocation à accueillir un fort
trafic (10000 connectés en simultanés pendant les heures de pointe)
c'est pour cette raison que je suis très soucieux de la montée en charge
du serveur.
Avatar
Mickael Wolff
On 16/01/11 23:11, Julien Arlandis wrote:

J'ai testé memcached et réalisé quelques tests :
L'accès aux données avec les sessions est presque 100 fois plus rapide
qu'avec memcached. Et si j'utilise les sockets unix avec memcached je
passe de 3800 ms à 2800 ms. Bien sûr cela ne signifie pas que memcached
est plus gourmand en ressource que la serialisation, mais les temps de
réponse du fait de l'utilisation des sockets sont nettement plus
importants. Que faut il privilégier, le temps de réponse du script php,
l'utilisation du processeur, la consommation mémoire? Pour information,
je suis en train de coder un site qui a vocation à accueillir un fort
trafic (10000 connectés en simultanés pendant les heures de pointe)
c'est pour cette raison que je suis très soucieux de la montée en charge
du serveur.



Attention à ce que tu mesures. Le tableau de session est déjà
déserialisé quand on y accède en PHP. La déserialisation se fait à
l'ouverture de la session. Du coup tu utilises un tablean PHP.
Lorsque tu sauvegardes les données dans Memcache, tu sérialises (car
tu ne peux que sauver des chaines de caractères).

10 000 connectés simultanés n'entraîne pas nécessairement un fort
trafic ;) Ceci dit, si ton application doit être scalable, il faudra une
infrastructure scalable (backend de session adapté, caches répartis,
base de données shardable, etc). Et ça sort, je pense, du cadre de ce forum.
Avatar
Julien Arlandis
Le 17/01/2011 09:34, Mickael Wolff a écrit :
On 16/01/11 23:11, Julien Arlandis wrote:

J'ai testé memcached et réalisé quelques tests :
L'accès aux données avec les sessions est presque 100 fois plus rapide
qu'avec memcached. Et si j'utilise les sockets unix avec memcached je
passe de 3800 ms à 2800 ms. Bien sûr cela ne signifie pas que memcached
est plus gourmand en ressource que la serialisation, mais les temps de
réponse du fait de l'utilisation des sockets sont nettement plus
importants. Que faut il privilégier, le temps de réponse du script php,
l'utilisation du processeur, la consommation mémoire? Pour information,
je suis en train de coder un site qui a vocation à accueillir un fort
trafic (10000 connectés en simultanés pendant les heures de pointe)
c'est pour cette raison que je suis très soucieux de la montée en charge
du serveur.



Attention à ce que tu mesures. Le tableau de session est déjà
déserialisé quand on y accède en PHP. La déserialisation se fait à
l'ouverture de la session. Du coup tu utilises un tablean PHP.
Lorsque tu sauvegardes les données dans Memcache, tu sérialises (car tu
ne peux que sauver des chaines de caractères).



Effectivement, c'est ce que je viens de vérifier, cette fois ci j'ai
modifié le php.ini pour rediriger les sessions dans memcache.

<?php

$mem = new Memcache;
$mem->connect('localhost', 11211);

$ms = microtime(true);
for($i=0;$i<10000;$i++)
{
$champ = 'toto'.$i;
$_SESSION[$champ] = 1;
}
echo (int)((microtime(true) - $ms) * 1000) . " ms <br/>";

$ms = microtime(true);
for($i=0;$i<10000;$i++)
{
$champ = 'toto'.$i;
$mem->set($champ, 1);
}
echo (int)((microtime(true) - $ms) * 1000) . " ms <br/>";
?>

La première boucle retourne 3 ms
et la seconde 386 ms.
Conclusion, la sérialisation ne doit avoir lieu qu'une seule fois, php
doit faire un get à l'ouverture de la session et un set à la fermeture.


10 000 connectés simultanés n'entraîne pas nécessairement un fort trafic
;) Ceci dit, si ton application doit être scalable, il faudra une
infrastructure scalable (backend de session adapté, caches répartis,
base de données shardable, etc). Et ça sort, je pense, du cadre de ce
forum.



Pour le backend de session je pense qu'un serveur memcache devrait
largement suffire, pour la répartition des caches je n'ai pas encore
réfléchi à la question, que me conseillez vous? Sur mon site les membres
sont appelés à uploader des documents qui seront accessibles en lecture
via un flush php. Je pense qu'il faudrait stocker les fichiers sur un
serveur à part mais comment éviter le goulot d'étranglement sur les I/O
du disque dur ?
Pour les bases de données j'ai pensé mettre mysql en cluster.
Avatar
Mickael Wolff
On 17/01/11 22:26, Julien Arlandis wrote:

Conclusion, la sérialisation ne doit avoir lieu qu'une seule fois, php
doit faire un get à l'ouverture de la session et un set à la fermeture.


Tout à fait.

Pour le backend de session je pense qu'un serveur memcache devrait
largement suffire,


Avec Memcache, il y a quelques éléments auxquels il faut prêter
attention à :
- la limite à 1Mo de la valeur associée à la clé
- la volatilité des données
- l'accès non-sécurisé des données (il n'y a pas de mécanisme
d'autentification dans Memcache)

pour la répartition des caches je n'ai pas encore
réfléchi à la question, que me conseillez vous?


L'accès aux données confiées à un cluster Memcache est indiférencié.
En gros, quand tu intéroges un serveur Memcache, il pose la question à
quelques autres serveurs, et donne le résultat cohérent. Je n'ai pas les
détails de l'algo en tête. Mais le code source est très clair et simple.
Quand tu ajoutes un serveur Memcache, il suffit de le dire aux autres
(ou un autre, je n'ai jamais déployé du Memcache, uniquement travaillé
avec).

Sur mon site les membres
sont appelés à uploader des documents qui seront accessibles en lecture
via un flush php. Je pense qu'il faudrait stocker les fichiers sur un
serveur à part mais comment éviter le goulot d'étranglement sur les I/O
du disque dur ?


Raid, proxy, round robin, usine à gaz :o) Mais ce n'est pas le sujet
du forum.

Pour les bases de données j'ai pensé mettre mysql en cluster.


Tu peux tenter de lever un troll sur comp.lang.sgbd si tu t'en sens
le courage :D Ceci dit, regardes les derniers développements de MySQL.
1 2