Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Symfony reload the User from the database on each request?

Tags:

php

symfony

From the Symfony 2 cookbook: Understanding serialize and how a User is Saved in the Session:

Once the user is logged in, the entire User object is serialized into the session. On the next request, the User object is deserialized. Then, value of the id property is used to re-query for a fresh User object from the database.

and,

... in practice, this means that the User object is reloaded from the database on each request using the id from the serialized object.

Why is it necessary for Symfony to fetch the User object from the database on each request?

Under what circumstances would the serialised User object that is stored in the session data not match up with the User object fetched from the database? Surely Symfony knows when the User object changes, and can simply update the session data when this occurs?

I imagine that there is a good reason for this, since it would be wasteful to unnecessarily query the database on each request.

like image 570
Richard Keller Avatar asked Mar 04 '14 11:03

Richard Keller


2 Answers

Under what circumstances would the serialised User object that is stored in the session data not match up with the User object fetched from the database?

For example when the admin changes what rights/permissions a user has – that is usually something you want to be effective immediately, and not just when the user logs out and then in again the next time.

Surely Symfony knows when the User object changes, and can simply update the session data when this occurs?

Not when that change has no connection to the user’s session, as is the case in the aforementioned scenario.

like image 163
CBroe Avatar answered Nov 18 '22 21:11

CBroe


Disclaimer: I don't know Symfony specifically, so this is written from general PHP knowledge and a couple of assumptions.

PHP sessions aren't generally manipulable from outside - they're just a serialised blob of data in a file or memory store. The only way to change one is to deserialize it, make a change, and reserialize the whole thing - which is usually only done when you are "in" that session.

So if the user's details change outside the logged in session, the serialized blob will stay out of date. This would be a particular issue, for instance, if an admin revoked the user's access rights.

A cache such as memcached might store details of each user, and be explicitly flushed/changed on edit, but that would be considered part of the database fetch (the memcached layer acting as a faster access to the database data), not the session handling.


As haltabush asked in a comment: if the user is fetched on every request, why serialize it at all?

The answer is that enough information needs to be stored in the session to identify which user is logged in, and fetch their full details on the next page load. This could be as simple as storing the user ID, but by making use of the Serializable interface, Symfony can leave it up to a particular implementation to decide which fields should be saved to the session, and which should be re-fetched when it is unserialized.

It also leaves open the option for an implementation to save all the details of the user into the session, and "refresh" on a more relaxed basis, e.g. after a set time or number of requests, as discussed on this related question.

like image 13
IMSoP Avatar answered Nov 18 '22 22:11

IMSoP