NYCPHP Meetup

NYPHP.org

[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