english

learn php

10. sessions & cookies
8 minutes / 1518 words

ten

sessions and cookies

if you've spent any time on the internet, you've certainly heard about cookies. if you've heard any discussions about cookies, you've likely heard people talking about sessions and state, too.

state refers to keeping track of information about a user outside the program. there are lots of ways to do that but two of the most common, certainly ubiquitous on the internet, are using sessions and cookies.

before we talk about the difference between them and how to use them in php, we should probably discuss why state matters. or, perhaps to put it a better way, without state, there would be no meaningful modern web. that might sound like an exaggeration but it isn't. state is fundamental to ecommerce, logging into sites, user accounts and nearly every other task performed on the web today. without state, there could be no gmail, no wikipedia, no netflix, no spotify and no google docs.

imagine you are using a site and you are asked for your username and password so you type them in and click login. you get a response telling you that you've successfully logged in and a menu of tasks. so you click to open a photo you uploaded before. how does the program that receives the request for the photo know you're the same user who successfully logged in?

remember how a web server works. your browser looks the address up and sends a request then gets a response back. at that point, the connection is finished. the next action, clicking on the photo, is a separate request with a different set of information.

the answer is state.

state -- or, to put it more formally, "maintaining state" -- means that a user is followed through all the pages on your site with a unique identifier so the web server can tell each program that it's the same user. this allows things like submitting information on one page and it being used on another page or logging in once and doing multiple tasks. without maintaining state, you couldn't log in and send an email. you'd have to send your username and password along with the contents of the email or the server wouldn't know who was sending it.

how that works is, in simplified form, you are assigned an id code when you go to a page on a site for the first time. that identifier follows you every time you send a new request. so, in effect, it's like the program you run second is just picking up where the first left off and can use some of the same information. that whole experience for the user is called a session. the user's session begins when they load the first page and ends either when they log out (in which case the session identifier is reset) or a certain amount of time has passed. the amount of time can be a few minutes or a few months. it's just a number you set on the server.

php treats the session as an array, just like $_POST and $_GET. it doesn't appear automatically, though. you have to tell it to start the session.

session_start();

to manually end a session is just as simple. this is something you can do if, for example, a user clicks the logout button.

session_destroy();

you can set and access information in the session variable anywhere in your program as long as you've run session_start. you do have to run it every time you start a new php program. if the user has a session identifier, it will access that user's existing session. if not, it will create a new identifier. you don't have to specify which task to perform.

if this is in one php program...

session_start();
$_SESSION["name"] = "lori bratt";
$_SESSION["email"] = "[email protected]";

then the same user runs another program containing...

session_start();
print_r("hi, " . $_SESSION["name"] . ". is your email " . $_SESSION["email"] . "?");

it returns hi, lori bratt. is your email [email protected]?.

you can treat the session array and its contents just like any other variables in php.

$userInformation=["name" => $_SESSION["name"], "email" => $_SESSION["email"]];

cookies

the difference between session variables and cookies is where they're stored. the session remains on the server. the user never sees the variables. they can access the session id but nothing stored in $_SESSION. that means they can't change it. so you can use it to store things like whether they've logged in successfully or whether their account has been restricted from seeing something.

cookies are stored on the user's computer. they can change them, delete them or even copy them to other devices.

for example, if a user logs in, you might want to load their profile information from a database or text file into $_SESSION for easy access page to page without having to keep hitting the storage system. you might also want to save their email as a cookie so, even if they log out, it will fill their email in the next time they come to the site. they can delete or change it if they want but it doesn't impact your site's security.

in much the same way, if a user is playing a game, you might store their score in a session variable, where they can't change it to cheat. but you might store their most recent signature line as a cookie because it doesn't impact security but is useful to be able to access it for weeks or months at a time, even login to login.

cookies behave a little differently from the $_SESSION array because they contain mandatory expiry information.

setcookie("language", "en", time() + 365 * 24 * 60 * 60);

if you don't specify an expiry, that means it disappears when the user quits the browser.

before we talk about how the expiry is calculated, we should mention unix timestamps. the unix epoch began january 1, 1970 at midnight utc. you might be curious what exactly happened on that particular day that makes it so special. like all other calendar breakpoints in history, this one is completely arbitrary.

if you think about the common era, it began about 2000 years ago. why 2000 years? because a group of influential people decided that would be a good starting point. not because nothing happened before it but because it was convenient. other calendars have other arbitrary starting points. the chinese calendar has counted nearly 4800 years while the jewish calendar is getting close to 5800. the hindu calendar is approaching 2100, nearly sixty years ahead of the common era calendar.

while the western calendar measures time in years, months, weeks, days, seconds and many other increments, unix time is measured in seconds.

february 14, 1520 is the fifteen-hundred-twentieth year of the common era, two months and fourteen days in. unix time 300 is five minutes after midnight, january 1, 1970.

we talk about dates in the western calendar being bce or ce -- before the common era or in the common era. unix time does the same with positive and negative numbers.

for time quantities smaller than a second, it treats them as decimals.

php gives us the function time that returns the current unix time. so we don't have to worry about converting the date and time to the number of seconds since 1970. it does that for us. in fact, that's how the server, if it's running linux, bsd, macos or many other operating systems, already thinks of time behind the scenes.

so we can just treat time() as a number of seconds and use it as if it was a numeric variable. here, we've added exactly one year in seconds to it -- 365 * 24 * 60 * 60 is 365 days, 24 hours a day, 60 minutes an hour, 60 seconds a minute. it works out to 31536000 in a standard year. so the cookie expires today, a year from now.

the vernal equinox in 2000 was march 20 at 7.35.24. in unix time, that's 953550324.

the autumnal equinox in 1700 was september 23 at 2.28.19. in unix time, that's -8497418449.

a good practice with cookies is to keep renewing them when users come back. that way, in this case, the language they've set would remain for a year after their most recent visit, not from their first visit.

to access cookies, you don't need a special command. you can just treat $_COOKIES as an array the same as $_SESSION.

$_COOKIE["language"] = "en"

there is a fourth parameter for setcookie, defining the scope. in other words, how much of the site can access the cookie. if you want to restrict access to information, there is likely a reason it shouldn't be a cookie. if you find yourself using the scope parameter of setcookie, that's a good sign it should be either in the session variables or stored somewhere on the server for later retrieval.

warning

when you're using session variables and cookies, it is important to check to make sure they are set before using them. remember, the user can end a session or delete a cookie at any time without notifying your program. don't assume that, just because something was a string on the last page, it's not null now -- or a completely different value.

assignments

© avi sato. creative commons attribution-noncommercial-noderivatives.