views:

8079

answers:

6

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!

+12  A: 

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. otherwise it would not be able to deserialize the object from the session store.

cruizer
Thanks! That fixed a bug for me :D
Matt Ellen
for me too. Up vote for you, sir.
Jonathan Fingland
and for me too -- thanks!
Derek Kurth
+3  A: 

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)

Hank Gay
weld? what do you mean? can you explain your point in more details and why is it a rule of thumb?
tharkun
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. To be continued…
Hank Gay
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). To be continued…
Hank Gay
I wonder how would you implement complex applications over HTTP without welding state somehow
Vinko Vrsalovic
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. To be continued…
Hank Gay
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. 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. TBC…
Hank Gay
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. TBC…
Hank Gay
@VinkoYou 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, e.g., a hidden input. If you *really* need server-side tracking of state, it should probably be in your backing datastore.
Hank Gay
please edit your answer to include all these comments. it's easier to read and better for the wiki and anyways I can't chose your answer as the accepted one, if everything important is in the comments. thanks!
tharkun
You make it sound like sessions is the root of all evil code, its not. On larger dynamic sites its hard not to use sessions. Not so sure its a good thing to use it for objects though
John
+5  A: 
  • 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.

Vinko Vrsalovic
+1  A: 

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.

Marc Gear
+1  A: 

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.

Johnny
So, is it better to rebuild the object including doing all the database queries again? Because one of my thoughts for doing this was that I don't have to query the db for the same stuff again.
tharkun
If it's important to you that it won't query the database again use caching instead of storing it in the session. But please before doing anything like building caching check whether it is really a performance hit.
Johnny
Thanks, I actually think it's not. I should just query again.
tharkun
+3  A: 

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.

Greg