[PHP Sessions] [Tommy MacWilliam, Harvard University] [This is CS50.] [CS50.TV] Sessions in PHP can be used to implement functionality, like user logins, in your web app. PHP sessions allow you to associate information with the user's entire browsing session rather than simply a single page. So that means as the user visits various PHP pages that make up your website, any information in the session will persist. So that means that data stored in the session by one page can later be accessed by another page. Storing information in a session is easy, and we do so via the dollar sign, underscore, capital SESSION variable. Dollar sign, underscore, SESSION—just like dollar sign, underscore, GET and dollar sign, underscore, POST— is an associative array consisting of key value pairs. So we can use syntax—like dollar sign, underscore, SESSION, bracket, quote, foo, quote, bracket, equals, quote, bar, quote— to store the value "bar" in the key "foo." However, before we can write or read from the session array, we'll need to call a special function— session, underscore, start, ()— and this will initialize the session. So let's take a look at an example. Our first page, hello.php, uses the session to output some data to the user. Remember, we'll need to use session_start before we can access any session data. Now we're using PHP's isset to determine if a key exists in the $_SESSION associative array. If that key exists, that means the user has logged in, so we'll display the user's name. If that key is not set, that means the user hasn't logged in yet, so we'll display a link to login.php. So let's take a look at login.php. Down here, we have a single HTML form with a single input. The form's action attribute is $_SERVER ['PHP_SELF'], and this simply means that we want the form to be submitted to the current file, which, in this case, is login.php. So let's go back to the top of this file. If the user submitted the form, then $_POST['name'] must be set. For more information about HTML forms and post, check out the PHP Web Development video. In the case that the user did submit the form, we'd like to write the value that they typed in into the session. Now we can redirect the user to hello.php. Because we've stored the user's input into the session, hello.php will be able to access the value that was set in login.php. So let's check this out in a web browser. First, we'll navigate to http://localhost/hello.php. We can see here that we haven't logged in yet, so let's click the login link, which will redirect us to login.php. Okay, I'll type in my name, which will then be stored in the session. Great! Now we can see my input from login.php on hello.php via the session. So, what about logging the user out? Well, in order to log the user in, we simply stored a value into session name. So to log the user out, we simply need to remove that name key from the session array. So let's take a look at this last file, logout.php. Once again, we'll need to call session_start() before we can do anything session related. Now we can simply call session_destroy(), which will take care of getting rid of all the data in the session and then redirect the user back to hello.php. So if I click on the Log out link, we can see that the server has forgotten who I am, and I am no longer logged in. So what's going on here underneath the hood? In order to get the behavior we just saw, our server needs to do 2 things. First, the server needs to somehow store the data in the session. The different PHP files that comprise a website are executed as separate invocations of the PHP interpreter so local variable cannot be shared between them. Instead, the server needs to store our session data in some place that multiple .php files can access. Second, the server needs to associate the session data with only my browsing session. When I login to Facebook, there are probably millions of other people also logged into Facebook at the same time. But the server needs some way of associating my data with my current session and someone else's data with another session. Luckily, the authors of PHP thought about all of this for us, so we don't need to implement any of this ourselves. But let's take a look at what PHP does by default. When I visit a PHP page containing session_start for the first time, PHP will generate a large random value. Until session_destroy is called—or I don't visit any PHP pages on that site for a while— that random and probably unique value will be associated with me. That way the server has some way of identifying my browsing session as opposed to someone else's. We can take a look at the current session ID using the PHP function, session_ID. Here we're simply outputting the value of our session identifier. So if we again login to the example web app, and now navigate to sessid.php, we'll see this long string of characters, and that's the current identifier for my session, and that's how the server is keeping track of who I am. Okay, but we've only solved half the problem. Sure, the server now has some way of identifying me, but when I visit another page, the server needs to reuse that same identifier rather than generating a new one. Remember, if I declare a local variable in foo.php and then visit bar.php, bar.php has no way of knowing what happened in foo.php. So the default php session implementation requires that the browser remind the server which session ID to use. This is implemented in the form of a cookie. A cookie—in addition to being a delicious snack— is simply a small text file on your computer that a server can write to via the web browser. So after PHP generates my unique session ID via session_start, it's going to tell the web browser to store that identifier in a local text file, or a cookie. Then the web browser will include that identifier in every request that it makes to the server. So really, the web server isn't remembering who I am. Instead, the web browser is simply remembering the unique identifier that was generated by PHP and then constantly reminding the server what that identifier is. That way, information like my user name is stored on the server not my web browser. The browser simply tells the server where PHP stored that information so PHP can retrieve it. So that begs the question, where is PHP actually storing this information? By default, PHP will store your session data in a file inside of /tmp, or the 'temp' folder. The name of that file will include the session ID so PHP can determine which file to read and write from via only the session ID. All right. So let's open up the Network tab in Chrome's debugger via the wrench icon at top right. Now let's head to hello.php again. Let's click on the HTTP request to hello.php and then click on Headers. Here we can see that the cookie header contains a key called PHPSESSID, or PHP session ID—with a value that is that same long string we saw when we visited sessid.php. This is exactly how the browser is reminding the server what session ID should be used. It's including it in an HTTP header. All right. Let's head back to the terminal. Let's navigate to /tmp, where PHP is storing the session information by default. Sure enough, inside of this temporary folder, here's a file that contains the same exact session ID. If we open up this file, we can see how PHP is representing my session on disk. Here the string "Tommy" is being stored for the key 'name,' which is exactly what we were expecting. And that's an overview of sessions in PHP. What we just saw was only the default implementation of sessions. In fact, many websites change this default behavior to store PHP sessions more efficiently in the interest of improving performance. My name is Tommy, and this is CS50. [CS50.TV]