[nycphp-talk] preventing randomized session variable from changing when page is refreshed
David Krings
ramons at gmx.net
Wed Aug 20 21:13:40 EDT 2008
Kristina Anderson wrote:
> Yes, but if I do $_SESSION['cart_id'], it is effectively the same
> thing, I'm using this random string as an identifier for the unique
> cart. This is effectively the same as $_SESSION['session_id'] -- only
> the name is different.
And there is no reason to name it differently. I have a script using sessions
extensively and create a temporary folder using the session string. I have
code in place that checks if the directory already exists, but session IDs
generated by PHP are so unique that I yet have to see that code getting
executed - and that after I don't know how many ten thousand times. I agree
with John that there is absolutely no reason to generate your own ID.
> the unique identifier is generated when index.php loads, and is passed
> as a querystring throughout the user's shopping and each product they
> view/order is tagged with their unique identifier.
Which isn't necessary if you run session_start() at the top of each page
before executing any other code and sending anything to the browser.
> The problem is that if they refresh/reload index.php...that value will
> change and their cart will be nuked. Which will be bad.
Not if you use session_start() as John rightfully mentioned already. As far as
I know session_start() checks if the requesting browser connection ever
started a PHP session and if yes, it uses the same session ID again, otherwise
it generates a new one. And that is exactly that you want. You have an entry
point such as a login or a "Shop 'til you drop now" button or in your case the
index.php. When the browser requests that resource for the first time
session_start() will not find any session ID for that requesting browser
session. So it creates a new one that can be retrieved via session_id(). And
that ID does not change when each consecutive script calls session_start()
before executing any other code and before sending anything to the browser. So
when you have session_start() as the first line after the opening tag in the
index.php two things can happen:
a) the current browser connection never had a session ID and a new one is
generated
b) the current browser connection has already a session ID established and
uses that one
Especially case b) allows for a browser to call index.php as many times as
desired and any consecutive request will cause that PHP / the web server
always end up with exactly the same session ID. And what is even better, PHP
takes care of getting this to work even when the requesting browser does not
accept cookies. I think PHP's session handling is absolutely awesome and makes
things so much easier. I key everything off the session ID, even the name of
temporary tables in MySQL (you just need to add a _ in front of the ID to
prevent illegal table names to occur). And the big master key for everything
is always in place when you just make sure that the first thing to do in a
script is call session_start().
I have the bad habit to start writing all kinds of things into the session
array because it gets conveniently carried around for me, but I guess in a
serious application that involves money you want to keep things on the server.
> One thing that I just thought of a couple minutes ago would be to just
> use index.php to generate that...then include a new page and exit
> index.php so they won't ever be going back to that page during the
> session.
Well, but they DID get to the initial index.php in the first place, so they
can get back there again, just by using the back button of their browser.
Using session_start() will even take care of that.
>
> As for why I do things the way I do...I am using $_SESSION and not just
> $_GET which may not have been clear from what I posted.
>
I found only one case where GET saved the day in all the years I deal with PHP
(well, on your schedule it ends up to be maybe only a few months). POST or
keeping things on the server side and keying off a session ID is better.
What you could do is add code to the index.php to fire some housecleaning
script that takes care of stale carts. In my projects I store the session ID
with the user ID and the date / time of login in a table. Each time the main
page gets loaded I run a quick check against the date / time field and see if
there are any stale logins. Anything older than a day is considered stale and
I ditch any temporary directories, tables, and eventually the login entry
itself. That works reasonably well for my purposes and cleans up the crud for
all those cases where the user did not log out, which I assume will happen
often. I doubt that my approach scales well as I hit the database once for
typically nothing and potentially end up cleaning up a lot of stuff. For
example on one day I end up with 50000 stale sessions and two days later the
next user comes along and now I start this big cleanup and let that poor
bastard wait until I'm done. What might be better is to write the login info
into a flat file so that a cron / scheduled job can run during slow times and
kick off a script that does the house cleaning then. There may also be better
solutions.
Basically, I can only nod in agreement with what John wrote, you do want to
use session_start().
David
More information about the talk
mailing list