22. Using Session Control in PHP

In this chapter, we discuss the session control functionality in PHP, which is a common method of storing and reusing data specific to a user across multiple access points within your web application.

Key topics covered in this chapter include

Image Understanding session control

Image Using Cookies

Image Steps in setting up a session

Image Session variables

Image Sessions and authentication

What Is Session Control?

You might have heard people say that “HTTP is a stateless protocol,” which is a true statement that essentially means that HTTP has no built-in way of maintaining state between two transactions. By this, we mean when a user requests one page, followed by another page, the HTTP protocol itself does not provide a way for you to tell that both requests came from the same user.

The idea of session control is to be able to track a user during a single session on a website. If you can do this, you can easily support logging in a user and showing content according to her authorization level or personal preferences. Additionally, you can track the user’s behavior, and you can implement shopping carts, among many other actions.

PHP includes a rich set of native session control functions, as well as a single $_SESSION superglobal available for your use.

Understanding Basic Session Functionality

Sessions in PHP are driven by a unique session ID, which is a cryptographically random number. This session ID is generated by PHP and stored on the client side for the lifetime of a session. It can be either stored on a user’s computer in a cookie (the most common method) or passed along through URLs.

The session ID acts as a key that allows you to register particular variables as so-called session variables. The contents of these variables are stored on the server. The session ID is the only information visible at the client side. If, at the time of a particular connection to your site, the session ID is visible either through a cookie or the URL, you can access the session variables stored on the server for that session. You have probably used websites that store a session ID in the URL. If your URL contains a string of random-looking data, it is likely to be some form of session control.

By default, the session variables are stored in flat files on the server. (You can change this behavior to use a database if you are willing to write your own functions; you’ll learn more on this topic in the section “Configuring Session Control.”)

What Is a Cookie?

Cookies are a different solution to the problem of preserving state across a number of transactions while still having a clean-looking URL. A cookie is a small piece of information that scripts can store on a client-side machine. You can set a cookie on a user’s machine by sending an HTTP header containing data in the following format:

Set-Cookie: name=value; [expires=date;] [path=path;]
[domain=domain_name;] [secure;] [HttpOnly]

This creates a cookie called name with the value value. The other parameters are all optional. The expires field sets a date beyond which the cookie is no longer relevant; if no expiry date is set, the cookie is effectively permanent unless you or the user manually delete it. Together, the path and domain can be used to specify the URL or URLs for which the cookie is relevant. The secure keyword means that the cookie will not be sent over a plain HTTP connection, and the HttpOnly keyword means that the cookie will only be accessible via HTTP and not to any client-side scripting languages such as JavaScript.

When a browser connects to an URL, it first searches the cookies stored locally. If any of the locally stored cookies are relevant to the domain and path being connected to, the information stored in the cookie or cookies will be transmitted back to the server.

Setting Cookies from PHP

You can manually set cookies in PHP using the setcookie() function. It has the following prototype:

bool setcookie (string name [, string value [, int expire = 0[, string path
[, string domain [, int secure = false] [, int httponly = false]]]]])

The parameters correspond exactly to the ones in the Set-Cookie header mentioned previously.

If you set a cookie in PHP using

setcookie ('mycookie', 'value');

then when the user visits the next page in your site (or reloads the current page), you will have access to the data stored in the cookie via $_COOKIE['mycookie'].

You can delete a cookie by calling setcookie() again with the same cookie name and an expiry time in the past. You can also set a cookie manually via the PHP header() function and the cookie syntax given previously. One tip is that cookie headers must be sent before any other headers; otherwise, they will not work; this is a requirement for standard use of cookies rather than a PHP limitation.

Using Cookies with Sessions

Cookies have some associated problems: Some browsers do not accept cookies, and some users might have disabled cookies in their browsers. (This is one of the reasons PHP sessions use a dual cookie/URL method, which we will discuss shortly.)

When you are using PHP sessions, you do not have to manually set any cookies. The session functions take care of this task for you by creating all the necessary cookies to match the session being created when the session functions are used.

You can use the function session_get_cookie_params() to see the contents of the cookie set by session control. It returns an array containing the elements lifetime, path, domain, and secure.

You can also use

session_set_cookie_params(lifetime, path, domain [, secure] [, httponly]);

to set the session cookie parameters manually.

If you want to read more about cookies, you can consult the cookie specification (“HTTP State Management Mechanism”) at http://tools.ietf.org/html/rfc6265.

Storing the Session ID

By default PHP sessions use cookies to store the session ID on the client side. The other built-in method PHP can use is adding the session ID to the URL. You can set this to happen automatically if you set the session.use_trans_sid directive in the php.ini file to On; it is off by default.

Use caution when turning this directive on, as it increases your site’s security risks. If this value is set to on, a user can email the URL that contains the session ID to another person, the URL could be stored in a publically accessible computer, or it may be available in the history or bookmarks of a browser on a publically accessible computer.

Alternatively, you can manually embed the session ID in links so that it is passed along with every link. The session ID is stored in the PHP constant SID. To pass this value along manually, you add it to the end of a link similar to a GET parameter:

<a href="link.php?<?php echo strip_tags(SID); ?>">

Please note that the strip_tags() function is used here to avoid cross-site scripting attacks.

Implementing Simple Sessions

The basic steps of using sessions in PHP are

1. Starting a session

2. Registering session variables

3. Using session variables

4. Deregistering variables and destroying the session

Note that these steps don’t necessarily all happen in the same script, and some of them happen in multiple scripts. Let’s examine each of these steps in turn.

Starting a Session

Before you can use session functionality, you need to actually begin a session. There are two ways you can do this.

The first, and simplest, is to begin a script with a call to the session_start() function:

session_start();

This function checks to see whether there is already a current session. If not, it will create one, providing access to the superglobal $_SESSION array. If a session already exists, session_start() loads the registered session variables so that you can use them. Therefore, it is essential to call session_start() at the start of all your scripts that use sessions. If this function is not called, anything stored in the session will not be available to the script.

The second way you can begin a session is to set PHP to start one automatically when someone comes to your site. You can do this by using the session.auto_start option in your php.ini file; we will look at this approach when we discuss configuration later in this chapter. Be aware this method has one big disadvantage: With auto_start enabled, you cannot use objects as session variables. This is because the class definition for that object must be loaded before starting the session to create the objects in the session.

Registering Session Variables

As previously mentioned, session variables are stored in the superglobal $_SESSION array. To create a session variable, you simply set an element in this array, as follows:

$_SESSION['myvar'] = 5;

The session variable you have just created will be tracked until the session ends or until you manually unset it. The session may also naturally expire based on the session.gc_maxlifetime setting in the php.ini file. This setting determines the amount of time (in seconds) that a session will last before it is ended by the garbage collector.

Using Session Variables

To bring session variables into scope so that they can be used, you must first start a session calling session_start(), as previously mentioned. You can then access the variable via the $_SESSION superglobal array—for example, as $_SESSION['myvar'].

When you are using an object as a session variable, it is important that you include the class definition before calling session_start() to reload the session variables. This way, PHP knows how to reconstruct the session object.

On the other hand, you need to be careful when checking whether session variables have been set (via, say, isset() or empty()). Remember that variables can be set by the user via GET or POST. You can check a variable to see whether it is a registered session variable by checking in $_SESSION.

You can check this directly using the following, for example,

if (isset($_SESSION['myvar']))
{
   // do something because the session variable is present
}

Unsetting Variables and Destroying the Session

When you are finished with a session variable, you can unset it. You can do this directly by unsetting the appropriate element of the $_SESSION array, as in this example:

unset($_SESSION['myvar']);

You should not try to unset the whole $_SESSION array because doing so will effectively disable sessions. To unset all the session variables at once, use the following code that clears out the existing elements in the $_SESSION superglobal:

$_SESSION = array();

When you are finished with a session, you should first unset all the variables and then call

session_destroy();

to clean up the session ID.

Creating a Simple Session Example

Some of this discussion might seem abstract, so let’s look at an example. Here, you’ll implement a set of three pages.

On the first page, start a session and create the variable $_SESSION['session_var']. The code to do this is shown in Listing 22.1.

Listing 22.1 page1.php—Starting a Session and Creating a Session Variable


<?php
session_start();

$_SESSION['session_var'] = "Hello world!";

echo 'The content of '.$_SESSION['session_var'].' is '
     .$_SESSION['session_var'].'<br />';
?>
<a href="page2.php">Next page</a>


This script creates the variable and sets its value. The output of this script is shown in Figure 22.1.

Image

Figure 22.1 Initial value of the session variable shown by page1.php

The final value of the variable on the page is the one that will be available on subsequent pages. At the end of the script, the session variable is serialized, or frozen, until it is reloaded via the next call to session_start().

You can therefore begin the next script by calling session_start(). This script is shown in Listing 22.2.

Listing 22.2 page2.php—Accessing a Session Variable and Unsetting It


<?php
session_start();

echo 'The content of $_SESSION['session_var'] is '
     .$_SESSION['session_var'].'<br />';

unset($_SESSION['sess_var']);
?>
<p><a href="page3.php">Next page</a></p>


After you call session_start(), the variable $_SESSION ['session_var'] is available with its previously stored value, as you can see in Figure 22.2.

Image

Figure 22.2 The value of the session variable is passed along via the session ID to page2.php

After you have used the variable in this listing, you unset it. The session still exists, but the variable $_SESSION['session_var'] no longer exists.

Finally, you pass along to page3.php, the final script in the example. The code for this script is shown in Listing 22.3.

Listing 22.3 page3.php—Ending the Session


<?php
session_start();

echo 'The content of $_SESSION['session_var'] is '
     .$_SESSION['session_var'].'<br />';

session_destroy();
?>


As you can see in Figure 22.3, you no longer have access to the persistent value of $_SESSION['session_var'].

Image

Figure 22.3 The session variable is no longer available

You finish your script by calling session_destroy() to dispose of the session ID.

Configuring Session Control

There is a set of configuration options for sessions that you can set in your php.ini file. Some of the more useful options, and a description of each, are shown in Table 22.1. Additionally, you learned a few more configuration options related to session upload progress, in Chapter 17, “Interacting with the File System and the Server.”

Image

Table 22.1 Session Configuration Options

For a complete list of session configurations, please see the PHP manual at http://php.net/manual/en/session.configuration.php.

Implementing Authentication with Session Control

Possibly the most common use of session control is to keep track of users after they have been authenticated via a login mechanism. In this example, you combine authentication from a MySQL database with use of sessions to provide this functionality. This functionality forms the basis of the project in Chapter 27, “Building User Authentication and Personalization,” and will be reused in the other projects.

The example consists of three simple scripts. The first, authmain.php, provides a login form and authentication for members of the website. The second, members_only.php, displays information only to members who have logged in successfully. The third, logout.php, logs out a member.

To understand how this example works, look at Figure 22.4, which shows the initial page displayed by authmain.php.

Image

Figure 22.4 Because the user has not yet logged in, show him or her a login page

This page gives the user a place to log in. If the user attempts to access the Members Only section without logging in first, he or she will get the message shown in Figure 22.5.

Image

Figure 22.5 Users who haven’t logged in can’t see the site content; they will be shown this message instead

If the user logs in first (with username: testuser and password: password), however, and then attempts to see the Members page, he or she will get the output shown in Figure 22.6.

Image

Figure 22.6 After the user has logged in, he or she can access the Members Only areas

First, let’s look at the code for this application. Most of the code is in authmain.php, shown in Listing 22.4. Then we’ll go through it bit by bit.

Listing 22.4 authmain.php—The Main Part of the Authentication Application


<?php
session_start();

if (isset($_POST['userid']) && isset($_POST['password']))
{
  // if the user has just tried to log in
  $userid = $_POST['userid'];
  $password = $_POST['password'];

  $db_conn = new mysqli('localhost', 'webauth', 'webauth', 'auth');

  if (mysqli_connect_errno()) {
    echo 'Connection to database failed:'.mysqli_connect_error();
    exit();
  }

  $query = "select * from authorized_users where
            name='".$userid."' and
            password=sha1('".$password."')";

  $result = $db_conn->query($query);
  if ($result->num_rows)
  {
    // if they are in the database register the user id
    $_SESSION['valid_user'] = $userid;
  }
  $db_conn->close();
}
?>
<!DOCTYPE html>
<html>
<head>
   <title>Home Page</title>
    <style type="text/css">
      fieldset {
         width: 50%;
         border: 2px solid #ff0000;
      }
      legend {
         font-weight: bold;
         font-size: 125%;
      }
      label {
         width: 125px;
         float: left;
         text-align: left;
         font-weight: bold;
      }
      input {
         border: 1px solid #000;
         padding: 3px;
      }
      button {
         margin-top: 12px;
      }
    </style>
</head>
<body>
<h1>Home Page</h1>
<?php
  if (isset($_SESSION['valid_user']))
  {
    echo '<p>You are logged in as: '.$_SESSION['valid_user'].' <br />';
    echo '<a href="logout.php">Log out</a></p>';
  }
  else
  {
    if (isset($userid))
    {
      // if they've tried and failed to log in
      echo '<p>Could not log you in.</p>';
    }
    else
    {
      // they have not tried to log in yet or have logged out
      echo '<p>You are not logged in.</p>';
    }

    // provide form to log in
    echo '<form action="authmain.php" method="post">';
    echo '<fieldset>';
    echo '<legend>Login Now!</legend>';
    echo '<p><label for="userid">UserID:</label>';
    echo '<input type="text" name="userid" id="userid" size="30"/></p>';
    echo '<p><label for="password">Password:</label>';
    echo '<input type="password" name="password" id="password" size="30"/></p>';
    echo '</fieldset>';
    echo '<button type="submit" name="login">Login</button>';
    echo '</form>';

  }
?>
<p><a href="members_only.php">Go to Members Section</a></p>

</body>
</html>


Some reasonably complicated logic is included in this script because it displays the login form, is also the action of the form, and contains HTML for a successful and failed login attempt.

The script’s activities revolve around the valid_user session variable. The basic idea is that if someone logs in successfully, you will register a session variable called $_SESSION['valid_user'] that contains his or her userid.

The first thing you do in the script is call session_start(). This call loads in the session variable valid_user if it has been created.

In the first pass through the script, none of the if conditions apply, so the user falls through to the end of the script, where you tell the user that he or she is not logged in and provide him or her with a form to do so:

echo '<form action="authmain.php" method="post">';
echo '<fieldset>';
echo '<legend>Login Now!</legend>';
echo '<p><label for="userid">UserID:</label>';
echo '<input type="text" name="userid" width="30"/></p>';
echo '<p><label for="password">Password:</label>';
echo '<input type="password" name="password" width="30"/></p>';
echo '</fieldset>';
echo '<button type="submit" name="login">Login</button>';
echo '</form>';

When the user clicks the submit button on the form, this script is reinvoked, and you start again from the top. This time, you will have a userid and password to authenticate, stored as $_POST['userid'] and $_POST['password']. If these variables are set, you go into the authentication block:

if (isset($_POST['userid']) && isset($_POST['password']))
{
  // if the user has just tried to log in
  $userid = $_POST['userid'];
  $password = $_POST['password'];

  $db_conn = new mysqli('localhost', 'webauth', 'webauth', 'auth');
  if (mysqli_connect_errno()) {
   echo 'Connection to database failed:'.mysqli_connect_error();
   exit();
  }

  $query = "select * from authorized_users where
            name='".$userid."' and
            password=sha1('".$password."')";
  $result = $db_conn->query($query);

Here you connect to a MySQL database and issue a query to check the userid and password. If they are a matching pair in the database, you create the variable $_SESSION['valid_user'], which contains the userid for this particular user, so you know who is logged in further down the track:

  if ($result->num_rows >0 )
  {
    // if they are in the database register the user id
    $_SESSION['valid_user'] = $userid;
  }
  $db_conn->close();
}

Because you now know who the user is, you don’t need to show him or her the login form again. Instead, you can tell the user you know who he or she is and give him or her the option to log out:

if (isset($_SESSION['valid_user']))
{
    echo '<p>You are logged in as: '.$_SESSION['valid_user'].' <br />';
    echo '<a href="logout.php">Log out</a></p>';}

If you tried to log the user in and failed for some reason, you’ll have a userid but not a $_SESSION['valid_user'] variable, so you can give him or her an error message:

if (isset($userid))
{
  // if they've tried and failed to log in
      echo '<p>Could not log you in.</p>';}

That’s it for the main script. Now, let’s look at the Members Only page. The code for this script is shown in Listing 22.5.

Listing 22.5 members_only.php—The Code for the Members Only Section of the Website Checks for Valid Users


<?php
  session_start();
?>
<!DOCTYPE html>
<html>
<head>
   <title>Members Only</title>
</head>
<body>
<h1>Members Only</h1>

<?php
  // check session variable
  if (isset($_SESSION['valid_user']))
  {
    echo '<p>You are logged in as '.$_SESSION['valid_user'].'</p>';
    echo '<p><em>Members-Only content goes here.</em></p>';
  }
  else
  {
    echo '<p>You are not logged in.</p>';
    echo '<p>Only logged in members may see this page.</p>';
  }
?>

<p><a href="authmain.php">Back to Home Page</a></p>

</body>
</html>


This code simply starts a session and checks whether the current session contains a registered user by checking whether the value of $_SESSION['valid_user'] is set. If the user is logged in, you show him or her the members’ content; otherwise, you tell the user that he or she is not authorized.

Finally, the logout.php script signs a user out of the system. The code for this script is shown in Listing 22.6.

Listing 22.6 logout.php—This Script Deregisters the Session Variable and Destroys the Session


<?php
  session_start();

  // store to test if they *were* logged in
  $old_user = $_SESSION['valid_user'];
  unset($_SESSION['valid_user']);
  session_destroy();
?>
<!DOCTYPE html>
<html>
<head>
   <title>Log Out</title>
</head>
<body>
<h1>Log Out</h1>
<?php
  if (!empty($old_user))
  {
    echo '<p>You have been logged out.</p>';
  }
  else
  {
    // if they weren't logged in but came to this page somehow
    echo '<p>You were not logged in, and so have not been logged out.</p>';
  }
?>
<p><a href="authmain.php">Back to Home Page</a></p>

</body>
</html>


This code is simple, but there’s a little fancy footwork involved. First you start a session, then store the user’s old username, unset the valid_user variable, and destroy the session. You then give the user a message that will be different if he or she was logged out or was not logged in to begin with.

This simple set of scripts forms the basis for a lot of the work we’ll do in later chapters.

Next

In the next chapter, we’ll take a little bit of a detour to client-side scripting with JavaScript, but specifically Ajax, which allows JavaScript to communicate with your web server. Communicating with your web server also means communicating with PHP scripts on that server, so we’ll take a look at client-side requests and server responses.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset