For the majority of my PHP career I didn’t store objects in a session. Not that it’s a difficult thing, I simply didn’t have a need to in the past. Now that I do, I have discovered a peculiar (in my opinion) aspect of it.
This came about because the session data on a certain area of the site in question would sometimes grow too large for the database field I was storing it in. PHP serializes the objects (to represent them as a string) before storing them in the session but when it isn’t able to store the entire string (which was happening for me), you end up with corrupted data which PHP can not unserialize back to object form. Once I zeroed in on this being the source of my problems, I needed a good solution.
Thankfully, I didn’t need to store every bit of the object since these objects had a number of protected properties I didn’t need to persist in my sessions. So the solution was simple, implement the Serializable interface PHP supplies. With this interface you are able to define the result of calling serialize() (and unserialize()) on an object. This is exactly what I wanted; I could now pick only the pieces of data I wanted to store and could greatly shrink down the size of my session data.
But it didn’t work! It was a mystery. I tested it by serializing an instance of one of these objects and I would get my expected result. When I tested it in the site my session would fill up with serialized versions containing the entire set of properties as before. I even tried using the magic methods __sleep() and __wakeup() but nothing was working. Why? Why???
Eventually, I found out the secret. I don’t recall now where I read it or how I came upon it but I now share that secret with you. When PHP serializes objects for sessions, it does so in a slightly different way. This means that it doesn’t care if you’ve implemented Serializable, or defined __sleep() in your classes. If you give PHP an object to put in a session, it does serialize it but using a “slightly different” method.
Why? I don’t know. There could be a very valid reason it needs to be that way, and that’s fine. Maybe this was common knowledge at some point but for me it was a little frustrating. But the lesson was learned:
Serialize your objects before storing them in the session
That’s the solution. Don’t give the session an object, give it a serialized version of the object and all will be well.