PHP: Storing 'objects' inside the $_SESSIO

2019-01-02 14:58发布

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!

8条回答
何处买醉
2楼-- · 2019-01-02 15:03

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.

查看更多
怪性笑人.
3楼-- · 2019-01-02 15:03

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.

查看更多
后来的你喜欢了谁
4楼-- · 2019-01-02 15:05

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.

查看更多
梦醉为红颜
5楼-- · 2019-01-02 15:08

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)

查看更多
呛了眼睛熬了心
6楼-- · 2019-01-02 15:19
  • 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.

查看更多
有味是清欢
7楼-- · 2019-01-02 15:20

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.

查看更多
登录 后发表回答