PHP Essentials, 2nd Edition
If the question is "How do I maintain user-specific information without setting multiple cookies and making numerous calls to a database?", then the answer is to use session management functions. In terms of time, a session is the amount of time during which a user visits a site. In the programming world, a session is kind of like a big blob that can hold all sorts of variables and values.
This blob of stuff, also known as a session object, has an identification string. This identification string, such as 940f8b05a40d5119c030c9c7745aead9, is automatically sent to the user when a session is initiated, via a cookie referred to as $_COOKIE[PHPSESSID]. On the server side, a matching temporary file is created with the same name-940f8b05a40d5119c030c9c7745aead9.
With your session object in place, you have a container that can hold all sorts of data, and generally make your life as an application developer much easier!
Understanding Session Variables
Each session object has variables registered with it, such as count or valid. Inside the session file on the server, the registered variables and their values are kept safe and sound. Since these values and variables are not kept in a database, no additional system resources are required to connect to and extract information from database tables.
For example, the session file might look like this:
count|s:7:"76"; valid|s:7:"yes";
where count and valid are the names of the registered variables, and 76 and yes are their respective values.
When you register a session variable, you eliminate the need to send additional cookies to the user. To assign values for count and valid to a user without using sessions, you'd have to send two separate cookies, like so:
setcookie("count","1",time()+14400,"/",".yourdomain.com",0); setcookie("valid","yes",time()+14400,"/",".yourdomain.com",0);
To access session variables, just reference their position in the $_SESSION super-global, like this: $_SESSION[count] or $_SESSION[valid]. When you use something like the following in your code:
echo "<P>$_SESSION[count]</p>";
the PHP engine takes the value of $_COOKIE[PHPSESSID] (the unique user session ID, stored in a cookie), matches it to a temporary session file, looks for count, finds its value (say, "76"), and returns it to your script.
Starting a Session and Registering Variables
We'll use a simple access counter to get used to the idea of sessions and session variables. At the beginning of your page, call the session_start() function. This function serves two purposes. First, it checks to see if a session has been started for this user and starts one if necessary. Second, it alerts the PHP engine that session variables and other session-related functions will be used within the specific script.
Open your favorite text editor, create a file called count_me.php, and type the following:
<?php // if a session does not yet exist for this user, start one session_start();
Next, register the count variable inside your session object:
session_register('count');
Now, for as long as this session exists, a variable referred to as $_SESSION[count] also exists. Currently, the variable has no value. However, if you increment it, it will have a value of "1":
$_SESSION[count]++;
Put these pieces together, and you'll have started a session if it hasn't already been started, assigned a session ID to a user if one doesn't exist, and registered the variable referred to as $_SESSION[count] and incremented it by 1 to represent the initial time the user has accessed the page.
Next, to display the value of the $_SESSION[count] session variable and show the user how many times he has accessed this page in his current session, just print the variable's value within a string:
echo "<P>You've been here $_SESSION[count] times. Thanks!</p>";
The entire access count code should look something like this:
<?php // if a session does not yet exist for this user, start one session_start(); session_register('count'); $_SESSION[count]++; echo "<P>You've been here $_SESSION[count] times. Thanks!</p>"; ?>
Reload the page a number of times, and watch the value of $_SESSION [count] increment by 1 each time. Though this may not be the most exciting example, you should now understand the basics of sessions.
Managing User Preferences with Sessions
Moving beyond the simple access counter, you can use sessions to manage your users' preferences when they visit your site. For example, you can have your users select their favorite font ($_SESSION[font_family]) and font size ($_SESSION[font_size]) for displaying site content.
In this example, you'll start a session, ask a user for his display preferences, display those preferences on subsequent pages, and allow the user to change his mind and reset the values.
For the first step, create a file called session1.php and start the session:
<?php // if a session does not yet exist for this user, start one session_start();
Immediately, begin an if...else construct that checks for any previously registered values:
if ((!$_SESSION[font_family]) || (!$_SESSION[font_size])) { $font_family = "sans-serif"; $font_size = "10"; $_SESSION[font_family] = $font_family; $_SESSION[font_size] = $font_size; } else { $font_family = $_SESSION[font_family]; $font_size = $_SESSION[font_size]; } ?>
This construct is important because it takes into consideration that, as the user must come back to this screen to reset his display preferences, the values of the variables must always be extracted from the session itself.
With the initial session-related code out of the way, create a simple HTML form that asks the user to select his font preferences:
<HTML> <HEAD> <TITLE>My Display Preferences</TITLE> <style type="text/css"> BODY, P, A {font-family:<? echo "$_SESSION[font_family]"; ?>;font-size:<? echo "$_SESSION[font_size]"; ?>pt;font-weight:normal;} H1 {font-family:<? echo "$_SESSION[font_family]"; ?>;font-size:<? echo $_SES- SION[font_size] + 4; ?>pt;font-weight:normal;} </style> </HEAD> <BODY> <H1>Set Your Display Preferences</h1> <FORM METHOD="POST" ACTION="session2.php"> <P>Pick a Font Family:<br> <input type="radio" name="sel_font_family" value="serif" checked> serif <input type="radio" name="sel_font_family" value="sans-serif"> sans-serif <input type="radio" name="sel_font_family" value="Courier"> Courier <input type="radio" name="sel_font_family" value="Wingdings"> Wingdings <P>Pick a Font Size:<br> <input type="radio" name="sel_font_size" value="8" checked> 8pt <input type="radio" name="sel_font_size" value="10"> 10pt <input type="radio" name="sel_font_size" value="12"> 12pt <input type="radio" name="sel_font_size" value="14"> 14pt <P><input type="submit" name="submit" value="Set Display Preferences"></p> </FORM> </BODY> </HTML>
Note that the style sheet contains in-line PHP code, to take into consideration the user's preferred (or default) font family and size. If you place this file on your Web server and access it with your browser, you should see something like that in Figure 6.1, with the default values in use.
In the next step, which creates the form action script (session2.php), we'll assign to the appropriate session variables the values selected by the user. Open your text editor and create a file called session2.php. Create a session in your code if one doesn't exist, and then check for values posted from the form. Next, check for previously stored values-but only if no values have been posted from the form. Finally, use default values if, for some reason, there are no values from the form or in a previous user session.
<?php // if a session does not yet exist for this user, start one session_start(); //check for registered values, or set defaults if (($_POST[sel_font_family]) || ($_POST[sel_font_size])) { $font_family = $_POST[sel_font_family]; $font_size = $_POST[sel_font_size]; $_SESSION[font_family] = $font_family; $_SESSION[font_size] = $font_size; } else if (((!$_POST[sel_font_family]) && (!$_POST[sel_font_size])) && (($_SESSION[font_family]) && ($_SESSION[font_size]))) { $font_family = $_SESSION[font_family]; $font_size = $_SESSION[font_size]; $_SESSION[font_family] = $font_family; $_SESSION[font_size] = $font_size; } else { $font_family = "sans-serif"; $font_size = "10"; $_SESSION[font_family] = $font_family; $_SESSION[font_size] = $font_size; } ?>
With the PHP code out of the way, move on to the HTML, including the dynamic stylesheet.
<HTML> <HEAD> <TITLE>My Display Preferences</TITLE> <style type="text/css"> BODY, P, A (font-family:<? echo "$_SESSION[font_family]"; ?>;font-size:<? echo "$_SESSION[font_size]"; ?>pt;font-weight:normal;} H1 {font-family:<? echo "$_SESSION[font_family]"; ?>;font-size:<? echo $_SES- SION[font_size] + 4; ?>pt;font-weight:normal;} </style> </HEAD> <BODY> <H1>Your Preferences Have Been Set</h1> <P>As you can see, your selected font family is <strong><? echo "$_SESSION[font_family]"; ?></strong> and your font size is <strong><? echo "$_SESSION[font_size]"; ?></strong>.</p> <P>Please feel free to <a href="session1.php">change your preferences</a> again.</p> </BODY> </HTML>
Save this file and place it on your Web server. If you go back and forth between session1.php and session2.php, changing your preferences as much as you like, you may end up with display preferences such as those shown in Figures 6.2 and 6.3.
This simple exercise shows how easy it is to use sessions to create dynamic, user-based Web sites.