PHP: Storing 'objects' inside the $_SESSION

PhpSessionObject

Php Problem Overview


I just figured out that I can actually store objects in the $_SESSION and I find it quite cool because when I jump to another page I still have my object. Now before I start using this approach I would like to find out if it is really such a good idea or if there are potential pitfalls involved.

I know that if I had a single point of entry I wouldn't need to do that but I'm not there yet so I don't have a single point of entry and I would really like to keep my object because I don't lose my state like that. (Now I've also read that I should program stateless sites but I don't understand that concept yet.)

So in short: Is it ok to store objects in the session, are there any problems with it?


Edit:

Temporary summary: By now I understand that it is probably better to recreate the object even if it involves querying the database again.

Further answers could maybe elaborate on that aspect a bit more!

Php Solutions


Solution 1 - Php

I know this topic is old, but this issue keeps coming up and has not been addressed to my satisfaction:

Whether you save objects in $_SESSION, or reconstruct them whole cloth based on data stashed in hidden form fields, or re-query them from the DB each time, you are using state. HTTP is stateless (more or less; but see GET vs. PUT) but almost everything anybody cares to do with a web app requires state to be maintained somewhere. Acting as if pushing the state into nooks and crannies amounts to some kind of theoretical win is just wrong. State is state. If you use state, you lose the various technical advantages gained by being stateless. This is not something to lose sleep over unless you know in advance that you ought to be losing sleep over it.

I am especially flummoxed by the blessing received by the "double whammy" arguments put forth by Hank Gay. Is the OP building a distributed and load-balanced e-commerce system? My guess is no; and I will further posit that serializing his $User class, or whatever, will not cripple his server beyond repair. My advice: use techniques that are sensible to your application. Objects in $_SESSION are fine, subject to common sense precautions. If your app suddenly turns into something rivaling Amazon in traffic served, you will need to re-adapt. That's life.

Solution 2 - Php

it's OK as long as by the time the session_start() call is made, the class declaration/definition has already been encountered by PHP or can be found by an already-installed autoloader. otherwise it would not be able to deserialize the object from the session store.

Solution 3 - Php

HTTP is a stateless protocol for a reason. Sessions weld state onto HTTP. As a rule of thumb, avoid using session state.

UPDATE: There is no concept of a session at the HTTP level; servers provide this by giving the client a unique ID and telling the client to resubmit it on every request. Then the server uses that ID as a key into a big hashtable of Session objects. Whenever the server gets a request, it looks up the Session info out of its hashtable of session objects based on the ID the client submitted with the request. All this extra work is a double whammy on scalability (a big reason HTTP is stateless).

  • Whammy One: It reduces the work a single server can do.
  • Whammy Two: It makes it harder to scale out because now you can't just route a request to any old server - they don't all have the same session. You can pin all the requests with a given session ID to the same server. That's not easy, and it's a single point of failure (not for the system as a whole, but for big chunks of your users). Or, you could share the session storage across all servers in the cluster, but now you have more complexity: network-attached memory, a stand-alone session server, etc.

Given all that, the more info you put in the session, the bigger the impact on performance (as Vinko points out). Also as Vinko points out, if your object isn't serializable, the session will misbehave. So, as a rule of thumb, avoid putting more than absolutely necessary in the session.

@Vinko You can usually work around having the server store state by embedding the data you're tracking in the response you send back and having the client resubmit it, e.g., sending the data down in a hidden input. If you really need server-side tracking of state, it should probably be in your backing datastore.

(Vinko adds: PHP can use a database for storing session information, and having the client resubmit the data each time might solve potential scalability issues, but opens a big can of security issues you must pay attention to now that the client's in control of all your state)

Solution 4 - Php

  • Objects which cannot be serialized (or which contain unserializable members) will not come out of the $_SESSION as you would expect
  • Huge sessions put a burden on the server (serializing and deserializing megs of state each time is expensive)

Other than that I've seen no problems.

Solution 5 - Php

In my experience, it's generally not worth it for anything more complicated than an StdClass with some properties. The cost of unserializing has always been more than recreating from a database given a session-stored Identifier. It seems cool, but (as always), profiling is the key.

Solution 6 - Php

I would suggest don't use state unless you absolutely need it. If you can rebuild the object without using sessions do it. Having states in your webapplication makes the application more complex to build, for every request you have to see what state the user is in. Ofcourse there are times where you cannot avoid using session (example: user have to be kept login during his session on the webapplication). Last I would suggest keeping your session object as small as possible as it impacts performance to serialize and unserialize large objects.

Solution 7 - Php

You'll have to remember that resource types (such as db connections or file pointers) wont persist between page loads, and you'll need to invisibly re-create these.

Also consider the size of the session, depending how it is stored, you may have size restrictions, or latency issues.

Solution 8 - Php

I would also bring up when upgrading software libraries - we upgraded our software and the old version had objects in session with the V1 software's class names, the new software was crashing when it tried to build the objects that were in the session - as the V2 software didn't use those same classes anymore, it couldn't find them. We had to put in some fix code to detect session objects, delete the session if found, reload the page. The biggest pain initially mind you was recreating this bug when it was first reported (all too familiar, "well, it works for me" :) as it only affected people who where in and out the old and new systems recently - however, good job we did find it before launch as all of our users would surely have had the old session variables in their sessions and would have potentially crashed for all, would have been a terrible launch :)

Anyway, as you suggest in your amendment, I also think it's better to re-create the object. So maybe just storing id and then on each request pulling the object from the database, is better/safer.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmarkusView Question on Stackoverflow
Solution 1 - PhpshanusmagnusView Answer on Stackoverflow
Solution 2 - PhpcruizerView Answer on Stackoverflow
Solution 3 - PhpHank GayView Answer on Stackoverflow
Solution 4 - PhpVinko VrsalovicView Answer on Stackoverflow
Solution 5 - PhpGregView Answer on Stackoverflow
Solution 6 - PhpJohnnyView Answer on Stackoverflow
Solution 7 - PhpMarc GearView Answer on Stackoverflow
Solution 8 - PhpMartynView Answer on Stackoverflow