[nycphp-talk] session variables: seven deadly sins
Paul Houle
paul at devonianfarm.com
Thu Dec 28 00:32:11 EST 2006
LK wrote:
> Paul,
>
> That looks like a lot of info to digest without specific examples. Is
> there a book or other resource on session management that you
> recommend that deals with these issues in more detail?
>
> Thanks.
> -Leo
>
I'm not aware of one, but I wish there was. I think the question
isn't so much "session management" but about how to manage state in a
stateless protocol -- sessions are one abstraction for doing that, but
other abstractions exist too.
I think the best approach here is the "Pattern Vocabulary"
approach. There are certain practices, that when applied to an
application, have certain results.
For instance, there's the pattern of "Stateless Server" -- the
complete state of the application (or subsystem thereof) is kept in
hidden POST and GET variables. You accept some limits, but get some
real benefits: infinite scalability, no headaches with the back
button, no need for cookies...
You might try the above and then notice that you're passing 100K
around in your hidden form variables... People are complaining that
your app is slow. Now you can generate a unique id each time you draw a
form ("Generated Form Scope", for lack of a better term.) You can
stuff your "hidden" variables into the database under this key, and
restore them when the key comes back... If your code is organized right
(does something like $vars=$_POST, and only looks at $vars
afterwards), you can do this transparently to the rest of your app.
The same kind of thinking can protect you against certain kinds of
back button woes -- you can at least stop people from submitting the
same form more than once, by checking to see if a form with that unique
id has been submitted before.
"Shopping Cart" is another pattern. People often use session
variables to handle shopping carts, but that's really not ideal from a
user interface perspective... Ideally, each instance of a shopping
cart has it's own unique id... Imagine we want to make an e-commerce
site that behaves like amazon.com:
(1) User visits e-commerce site from a home computer -- a long-term
tracking cookie gets stuck on their browser
(2) User adds item A to their shopping cart... A new shopping cart is
created with id #101, associated with the tracking cookie.
(3) User adds items B,C,D, and E to their shopping cart in the course of
30 minutes of browsing. Each time an item is added, we add a row to a
table in the database that links the item id to the shopping cart id.
(4) 4-year old hits reset button
(5) User comes back to e-commerce site... He's happy to find his cart is
still there. User creates account #202 to check out. Shopping cart
#101 is associated with account #202
(6) User checks out shopping cart.
(7) User comes back a week later, wants to buy a few more items. The
site recognizes who he is. He adds two of item A and an item F to a
newly created shopping cart with id #102, associated with user account
#202.
(8) User goes to work, logs in... The system sees that he has shopping
cart #102 open. He adds item G, and then checks out.
(9) User learns that he can trust this site to work correctly and
becomes a loyal customer.
It's nice that we've got a historical record of the shopping cart
after the fact, but there's a more important point -- we could have
lost the customer's dollar at many points in the above transaction if we
were using a $_SESSION based cart. The session wouldn't have survived
step 4, for instance. A good user interface isn't academic here... It
puts money in our pocket.
The above scenario is complex, and it might not be fair to expect
that a first-generation shopping cart has those features. A
$_SESSION-based shopping cart would need to be completely reworked to
add the features above. A cart that uses a unique "cart id" and
relational back end, will be a lot more maintainable... You could even
start out using $_SESSION to keep track of the "cart id", then keep it
in a cookie, then associate it with a user name, add the facility to
promote an anonymous cart to an authenticated cart and so on. Starting
with a good design, we can provide the interface that we ~want~ to
provide, not that one that our abstract layer ~forces~ us to provide.
More information about the talk
mailing list