185 votes

PHP : Stocker des 'objets' dans la $_SESSION

Je viens de découvrir que je peux en fait stocker des objets dans la $_SESSION et je trouve cela plutôt cool parce que lorsque je passe à une autre page, j'ai toujours mon objet. Avant de commencer à utiliser cette approche, j'aimerais savoir si c'est vraiment une bonne idée ou s'il y a d'autres façons de faire. pièges potentiels impliqué.

Je sais que si j'avais un point d'entrée unique, je n'aurais pas besoin de faire cela, mais je n'en suis pas encore là, donc je n'ai pas de point d'entrée unique et j'aimerais vraiment garder mon objet parce que je ne perds pas mon état comme ça. (J'ai aussi lu que je devrais programmer des sites sans état, mais je ne comprends pas encore ce concept).

Donc en bref : Est-il possible de stocker des objets dans la session, cela pose-t-il des problèmes ?


E

Résumé temporaire : Je comprends maintenant qu'il est probablement mieux vaut recréer l'objet, même si cela implique d'interroger à nouveau la base de données.

D'autres réponses pourraient peut-être être apportées développer cet aspect un peu plus !

130voto

shanusmagnus Points 1000

Je sais que ce sujet est ancien, mais cette question revient sans cesse et n'a pas été traitée à ma satisfaction :

Que vous sauvegardiez des objets dans $_SESSION, que vous les reconstruisiez entièrement à partir de données cachées dans des champs de formulaire ou que vous les interrogiez à nouveau à partir de la base de données à chaque fois, vous utilisez de l'état. HTTP est sans état (plus ou moins ; voir GET vs. PUT) mais presque tout ce que l'on veut faire avec une application web nécessite de maintenir un état quelque part. Agir comme si le fait de pousser l'état dans des coins et recoins équivalait à une sorte de victoire théorique est tout simplement faux. L'état est l'état. Si vous utilisez l'état, vous perdez les divers avantages techniques obtenus en étant sans état. Il n'y a pas lieu de s'inquiéter pour cela, sauf si l'on sait à l'avance qu'il faut s'inquiéter pour cela.

Je suis particulièrement déconcerté par la bénédiction reçue par les arguments de Hank Gay concernant le "double coup". L'OP construit-il un système de commerce électronique distribué et à charge équilibrée ? À mon avis, non, et je dirais même que la sérialisation de sa classe $User, ou autre, ne paralysera pas son serveur de manière irrémédiable. Mon conseil : utilisez des techniques adaptées à votre application. Les objets dans $_SESSION sont parfaits, sous réserve de précautions de bon sens. Si votre application se transforme soudainement en quelque chose qui rivalise avec Amazon en termes de trafic servi, vous devrez vous réadapter. C'est la vie.

114voto

cruizer Points 4821

C'est correct tant qu'au moment où l'appel à session_start() est fait, la déclaration/définition de la classe a déjà été rencontrée par PHP ou peut être trouvée par un autoloader déjà installé. sinon, il ne serait pas capable de désérialiser l'objet du magasin de session.

35voto

Hank Gay Points 36173

Ce n'est pas pour rien que le protocole HTTP est un protocole sans état. Les sessions soudent l'état sur HTTP. En règle générale, il convient d'éviter d'utiliser l'état de session.

UPDATE : Il n'y a pas de concept de session au niveau HTTP ; les serveurs fournissent ce concept en donnant au client un identifiant unique et en lui demandant de le soumettre à nouveau à chaque demande. Le serveur utilise ensuite cet identifiant comme clé dans une grande table de hachage d'objets Session. Chaque fois que le serveur reçoit une requête, il recherche l'information de session dans sa table de hachage d'objets de session en se basant sur l'identifiant que le client a soumis avec la requête. Tout ce travail supplémentaire est un double coup dur pour l'évolutivité (l'une des principales raisons pour lesquelles le protocole HTTP est sans état).

  • Premier coup dur : il réduit le travail qu'un seul serveur peut accomplir.
  • Deuxième inconvénient : il est plus difficile de faire évoluer le système, car il n'est plus possible d'acheminer une demande vers n'importe quel serveur - ils n'ont pas tous la même session. Il est possible d'épingler toutes les demandes avec un identifiant de session donné au même serveur. Ce n'est pas facile, et c'est un point de défaillance unique (pas pour le système dans son ensemble, mais pour une grande partie de vos utilisateurs). Vous pouvez également partager le stockage des sessions entre tous les serveurs de la grappe, mais vous devez alors faire face à une plus grande complexité : mémoire connectée au réseau, serveur de session autonome, etc.

Compte tenu de tout cela, plus vous mettez d'informations dans la session, plus l'impact sur la performance est important (comme le souligne Vinko). De plus, comme le souligne Vinko, si votre objet n'est pas sérialisable, la session se comportera mal. Donc, en règle générale, évitez de mettre plus que ce qui est absolument nécessaire dans la session.

@Vinko Vous pouvez généralement contourner le stockage de l'état par le serveur en incorporant les données que vous suivez dans la réponse que vous renvoyez et en demandant au client de la soumettre à nouveau, par exemple en envoyant les données dans une entrée cachée. Si vous vraiment a besoin d'un suivi de l'état côté serveur, il devrait probablement se trouver dans votre datastore de sauvegarde.

(Vinko ajoute : PHP peut utiliser une base de données pour stocker les informations de session, et le fait que le client soumette à nouveau les données à chaque fois peut résoudre les problèmes d'évolutivité, mais ouvre une grande boîte de problèmes de sécurité auxquels vous devez prêter attention maintenant que le client contrôle tout votre état).

18voto

Vinko Vrsalovic Points 116138
  • Les objets qui ne peuvent pas être sérialisés (ou qui contiennent des membres non sérialisables) ne sortiront pas de la $_SESSION comme vous vous y attendez
  • Les sessions volumineuses pèsent sur le serveur (la sérialisation et la désérialisation de mégaoctets d'état à chaque fois est coûteuse).

En dehors de cela, je n'ai rencontré aucun problème.

9voto

Greg Points 7391

D'après mon expérience, cela ne vaut généralement pas la peine pour quelque chose de plus compliqué qu'une StdClass avec quelques propriétés. Le coût de la désérialisation a toujours été plus élevé que la recréation à partir d'une base de données avec un identifiant stocké dans la session. Cela semble cool, mais (comme toujours), le profilage est la clé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X