So lets say we are doing an authentification system.
We are using php5 OOP for the system so there is:
class User {}
class User_Admin extends User {}
class User_Regular extends User {}
etc.....
What happens when we instantiate an object and we want it to persist among pages (using sessions) - you know...validating if user is there password etc.
So for example createing one User_Regular object we want this to keep track.
I see there is __sleep and serialize and stuff and maybe that is the way to go here on keeping the object through sesssion but would like to here
experience.
The reason is I haven't really used objects through sessions so far and since I already start using php5 extensivly would like to learn objects
tips and tricks on that matter.
10x
Sessions and Objects concern
Moderator: General Moderators
- John Cartwright
- Site Admin
- Posts: 11470
- Joined: Tue Dec 23, 2003 2:10 am
- Location: Toronto
- Contact:
I probably wouldn't ever use sessions to store objects, instead use registry and singleton patterns http://www.phppatterns.com/docs/design/the_registry or http://www.phppatterns.com/docs/design/ ... =singleton 
Well I have done stuff with serializing things into the session, for instance a user class
then all the methods in the user class that "change the state" of the class, call that save method afterwards, and at the top of my script I put something like
of course if your session is going to be saving itself a lot, you might want to just save it once at the end of the script rather then having it save itself after every method, but that isn't an issue in my script, as the only time the user changes state is logging in, or logging out.
Jcart, what is wrong with storing it like this? How do you persist an object from page to page? I know you use the registry but do you store the registry in the session at the end of the page execution?
Code: Select all
function save() {
$_SESSION['user'] = serialize($this);
}Code: Select all
$user = unserialize($_SESSION['user']);
if (!is_object($user)) {
$user = new user();
$_SESSION['user'] = serialize($user);
}Jcart, what is wrong with storing it like this? How do you persist an object from page to page? I know you use the registry but do you store the registry in the session at the end of the page execution?
- John Cartwright
- Site Admin
- Posts: 11470
- Joined: Tue Dec 23, 2003 2:10 am
- Location: Toronto
- Contact:
I guess I was looking at the class interaction of classes during a page load..
What I don't get is why would you want to keep the actual object, seems uneccesary to me. Why don't you simply save $_SESSION['loggedin'] = true; for example, along with other information.
Also I usually like to keep as little information floating around in the sessions as possible.. althought that comes down to personal preference (?)
What I don't get is why would you want to keep the actual object, seems uneccesary to me. Why don't you simply save $_SESSION['loggedin'] = true; for example, along with other information.
Also I usually like to keep as little information floating around in the sessions as possible.. althought that comes down to personal preference (?)
The reason I save the object is there is other information in the user object that I do not wish to lookup on each page load, plus a hash of their password is in the object, so on each page load on the __wakeup() method the user object "re validates" itself, if the user is logged in at two locations and changes their password in one, the other session is "no good" because the user class 'validates' itself, and notices it's password is invalid so it resets the user class (session_destroy would destroy other stuff in the session that I need), and then it saves itself, so now the user has a blank user object in their session.
Here is my take on it.
The main problem I see with saving the values in $_SESSION is that it makes all the objects values public. Ruining any ideas of encapsulation. At least to try and prevent any accidental overlapping you may want to do something like $_SESSION['oUser']['loggedIn'] = TRUE; Of course you need to figure out a standard for dealing with inheritance(I'd reccomend saving the value in whichever class defined the value first). In some cases it may be better to store composite values and work backwards when initializing. You may loose some data and speed doing that, but you help prevent object breakage. It does have some added benifits. For one, you can use lazy initialization and save on memory and loading speed.
So my reccomendation would be to store the values in the session array if you have a lot of data inside the objects, or multiple instances. However if the objects are small it may be quicker to serialize and unserialize them(benchmark it to check).
If your storing the values in the $_SESSION then you may want to look at OR/M as a lot of the ideas of persistance overlap.
For your case saving the actual values in the $_SESSION seems to make more sense, but thats just my two cents. You'll have to enforce policy rather than rely on code, though(i.e., no once should name a session with ``o'' followed by a capital letter unless your representing an object.).
The last option is to consider the real need for saving objects. Is it vital to your scripts working, or are you just adding excess bloat? Just manipulationg and checking $_SESSION['loggedin'], rather than actually saving it may not be so bad, at least in this case.
EDIT:
Second, what type of info is their that you can't save it outside the object.
The main problem I see with saving the values in $_SESSION is that it makes all the objects values public. Ruining any ideas of encapsulation. At least to try and prevent any accidental overlapping you may want to do something like $_SESSION['oUser']['loggedIn'] = TRUE; Of course you need to figure out a standard for dealing with inheritance(I'd reccomend saving the value in whichever class defined the value first). In some cases it may be better to store composite values and work backwards when initializing. You may loose some data and speed doing that, but you help prevent object breakage. It does have some added benifits. For one, you can use lazy initialization and save on memory and loading speed.
So my reccomendation would be to store the values in the session array if you have a lot of data inside the objects, or multiple instances. However if the objects are small it may be quicker to serialize and unserialize them(benchmark it to check).
If your storing the values in the $_SESSION then you may want to look at OR/M as a lot of the ideas of persistance overlap.
For your case saving the actual values in the $_SESSION seems to make more sense, but thats just my two cents. You'll have to enforce policy rather than rely on code, though(i.e., no once should name a session with ``o'' followed by a capital letter unless your representing an object.).
The last option is to consider the real need for saving objects. Is it vital to your scripts working, or are you just adding excess bloat? Just manipulationg and checking $_SESSION['loggedin'], rather than actually saving it may not be so bad, at least in this case.
EDIT:
Maybe I'm blind, but I'm not seeing how that could happen. The only way this could happen is if the user changes the password in the middle of an old script. That would cause an old cache of the $_SESSION data to be saved over the new data. This wouldn't invalidate the user, however. Since they still have a valid 'loggedIn' = TRUE;, and all the old data still seems to be valid(i.e. the old password hashes will still match). If your updating the user you should be updating the hash inside the User object as well. So, I'm not seeing how saving info outside an object allows for mismatching information.and notices it's password is invalid so it resets the user class
Second, what type of info is their that you can't save it outside the object.
I was referring too the user object validating it's hashed pass against the DB on each page call, so let's say the user is at the public library, and logs in.... all is good, they close the browser window and leave (assuming session cookie is not just persisting in memory only). They get home and forget they realized to log out. Rather then drive back they just change their password when they get home. Since the application validates the user on each page call all is good.
As to what it is saving, it is saving the username, the password (or rather the hash of the pass), an object called cart which is within the user object, the cart object contains 2 arrays, the first a list of items and the second a list of quantities. The cart object also contains a couple other variables about the state of the user's shopping cart.
Could I store this all in a session without serializing the object? yes. Could I rewrite my entire codebase to procedural? yes... I have bench-marked all my options and there is little overhead with serializing a few arrays. If my objects were much longer I probably would have done it differently. For the typical user object (user/password and 4-5 other small strings) the overhead is nominal.
err btw, regarding the loggedin=TRUE,
my user class has a validate method and a validate variable. the validate variable is not persisted between page calls but the users pass/username is. The validate method first checks if the validate variable is true, if so it returns true, otherwise is hits the DB with the username/pass. The class's constructor sets the validate variable to false, and any functions modifying the username or password also set the validate variable to false. In this way the DB get's hit only once per page, unless of course the password stored inside the object is changed during page execution. Now to think of it when the user is logged out it hits the DB everytime I call the validate() method... I need to fix that (ill switch validate to a 3-state, -1 means has been checked and is invalid, 0 hasnt been checked, 1 has been checked and validated :-p )
good thing this thing's still in the development stage
As to what it is saving, it is saving the username, the password (or rather the hash of the pass), an object called cart which is within the user object, the cart object contains 2 arrays, the first a list of items and the second a list of quantities. The cart object also contains a couple other variables about the state of the user's shopping cart.
Could I store this all in a session without serializing the object? yes. Could I rewrite my entire codebase to procedural? yes... I have bench-marked all my options and there is little overhead with serializing a few arrays. If my objects were much longer I probably would have done it differently. For the typical user object (user/password and 4-5 other small strings) the overhead is nominal.
err btw, regarding the loggedin=TRUE,
my user class has a validate method and a validate variable. the validate variable is not persisted between page calls but the users pass/username is. The validate method first checks if the validate variable is true, if so it returns true, otherwise is hits the DB with the username/pass. The class's constructor sets the validate variable to false, and any functions modifying the username or password also set the validate variable to false. In this way the DB get's hit only once per page, unless of course the password stored inside the object is changed during page execution. Now to think of it when the user is logged out it hits the DB everytime I call the validate() method... I need to fix that (ill switch validate to a 3-state, -1 means has been checked and is invalid, 0 hasnt been checked, 1 has been checked and validated :-p )
good thing this thing's still in the development stage