kylewolfe — 2012-11-14T13:05:24-05:00 — #1
I've been doing some reading and I've seen a lot of people stating that you must serialize an object before storing it in a session.
$_SESSION['userData'] = serialize($user);
I've found it difficult to find supporting documentation though. Why do we need to serialize before storing the object in a session?
Should these perhaps be avoided due to possible performance issues?
cups — 2012-11-14T13:36:48-05:00 — #2
How else can you store the state of the object then?
When we say session we mean a tmp file on the file system.
If your user only has one attribute "name" which is "Kyle" then arguably, perhaps it does not make a lot of sense, you might as well store a json encoded array or just $_SESSION['name'] variable.
But if the user object is storing a lot of data and perhaps even state, then serialize/deserialize provides a good framework/contract to store/get that data without having to "know" that the key you want is "name" as you attempt to unbundle it.
Maybe there are other checks that can be done to make sure you are unbundling the correct type of object.
lemon_juice — 2012-11-14T14:05:12-05:00 — #3
I don't think you have to serialize object for this purpose since PHP does it automatically. Sessions are stored as plain text (on disk or in a text field in a database) so in fact everything has to be serialized - simple variables, arrays and objects, otherwise sessions wouldn't work at all.
Another subject is if storing the user object in a session is worthwhile. Personally, I always store just the user ID in the session and recreate the object with fresh data from the database. This makes sense to me because if any of the user's data change in the mean time they are reflected on the page and are taken into account by the script. Otherwise, the script might deal with stale user data.
kylewolfe — 2012-11-14T14:21:23-05:00 — #4
I believe I read that Zend framework runs serialize() on everything thats passed through its session handler.
As I understand it, it'd be best to store any normally static data within the object in the session in order to prevent a db connection, and improve performance. If you are worried about an update to user details, why not update your user object that's in the session within your update function? This will ensure that your sessions user data is up to date and will require one less db connection per each page request.
lemon_juice — 2012-11-14T16:21:07-05:00 — #5
If that is the case it would be interesting to know what their reasoning was to serialize everything. Maybe they use some custom methods to store data in sessions? I don't know. What I know is that both arrays and objects can be stored directly in $_SESSION and retrieved without the need to serialize anything. PHP does it behind the scenes.
Fetching a single row by ID from the database is hardly affecting performance. Serializing/unserializing objects also affects performance. I don't think it's worthwhile to compare such tiny performance differences. If the data is really static then it might be reasonable to do as you suggest but user object is not that static - user data can be changed anytime, and although it would happen rarely it's important that any changes are applied immediately. If I ban a user I want it to happen now.
Yes, I could do it and it would work but in this case all updates have to occur by that one update function in that session. And this cannot be guaranteed. If an admin changes user's data then the update would not propagate to the user that is currently logged in because the admin and the user use separate sessions and as a result have access to two separate instances of the user object. Another case - as an admin I might want to quickly change user's data directly in the database outside my application. I want the changes to be recognized immediately by my scripts.
kylewolfe — 2012-11-14T16:28:36-05:00 — #6
I wonder if this was a semi-recent update to PHP and there was a need to keep this in Zend to maintain compatibility with older versions of PHP? I'll have to check this out later.
Well I think you would probably see less of a server load / page load time if you were able to reduce these. Though as you pointed out, things such as user access being revoked or not updated by the user himself would pose a problem.
lemon_juice — 2012-11-14T18:03:01-05:00 — #7
PHP 4 already serialized objects for session storage:
If you are using sessions and use session_register() to register objects, these objects are serialized automatically at the end of each PHP page, and are unserialized automatically on each of the following pages. This basically means that these objects can show up on any of your pages once they become part of your session.
And the current documentation for PHP 5 is here: http://php.net/manual/en/language.oop5.serialization.php
I wouldn't notice less of server load now because I don't manage a site with millions of users yet (but to be honest I'd really love to just for the challenge of it ). But anyway, for several reasons the user object must be always fresh in my case. A single SELECT by ID query runs in about 0.0006 seconds on one of my shared hosts so this is far from being noticeable :).
lemon_juice — 2012-11-14T18:49:51-05:00 — #8
Or perhaps there are some more subtle differences depending on whether you serialize an object by serialize() or you let PHP session mechanism do it. This could be a similar issue as with the __destruct() magic method. If you serialize() "by hand" then all your environment (class definitions) is still loaded and if your objects make use of __sleep(), __wakeup() or implement Serializable then these magic methods have access to all the environment. Serializing by the internal session mechanisms may happen after parts of the environment are already gone, memory is purged, etc., so the magic methods may not be able to do their work. This is just my speculation and this would need some more investigation.