Developer

Script Teez: Saving sessions in PHP

Sessions allow you to store a cookie in the user's browser that you can reference to obtain information. Vincent Danen shows you how to implement this PHP feature in his latest Script Teez.


With the advent of a very sophisticated programming language designed for the Web comes increasingly sophisticated Web sites. However, as an existing or potential Web designer or administrator, you might be a little lost as to where to begin to make your site more sophisticated and, perhaps, complex.

With more interactive sites comes more distributed information, and with more distributed information comes the question: “How are you going to keep track of it?”

For instance, imagine you have a Web site that allows users to log in and customize the look based on user preferences. One way you could accomplish this is to use a form that passed on hidden information to each page. Of course, you would need to have forms embedded on each page that provided those hidden tags. This is easy enough to accomplish in a questionnaire, but it is not very practical when it comes to having users navigating a Web site and not following particular links. For instance, once they hit the back button on their browser, the show's over, and the carefully planned form linking is broken. Another option is to embed the user's name or preferences directly into each link on a page. The problem here comes when a user bookmarks a single page without the appropriate information appended to the URL, which will make your site less consistent and makes it feel a lot less user friendly.

The best way to deal with this is to use sessions in PHP. Sessions allow you to store a cookie in the user's browser that you can reference to obtain information. By using this feature of PHP, you can start a session when users log in and destroy the session when they log out.

Of course, you must also think about the implementation. It might seem easiest to store information like the user's name and perhaps the password (don't laugh, it's been known to happen!) in a session, but this is an extremely insecure way of designing user-based authentication for a Web site. Cookies can be easily stolen from a browser, and if you store a password and username in the cookie, regardless of whether or not the password is encrypted, you make it easier for someone to break into your site. But I digress; this isn't a piece on Web site security.

Instead, let's take a look at a rather rudimentary Web page that illustrates the use of sessions in PHP so you can gain an understanding of how sessions can work for you and your site. I call this page test.php:
<?php
  // Start the session
  session_start();
  session_register("Username");

  if(isset($Name)) {
    $Username = $Name;
  }

?>
<html>
<head>
  <title>Test session page</title>
</head>
<body>
<?php
  // Print information on the session
  print("<p>Session Information</p>\n");
  print("Session Name: " . session_name() . "<br />\n");
  print("Session ID  : " . session_id() . "<br />\n");
  print("Session Module: " . session_module_name() . "<br />\n");
  print("Session Path  : " . session_save_path() . "<br />\n");
  print("Session Encode: " . session_encode() . "<br /><hr />\n");

  if(isset($Username)) {
    print("<p>Welcome back, $Username!</p>\n");
  }

  // This is the form where the username is submitted:
?>

<form action="<?php print($SCRIPT_NAME); ?>" method="POST">
<input type="text" name="Name" value="<?php print($Username); ?>"><br />
<input type="submit" value="Change Name">
</form>
</body>
</html>


The basic idea of this script is to have the user enter his or her name in a single field form. The form reloads the page with the information, and if the name is set, a PHP session is created. Statistical information about the session (which is only useful for debugging and seeing what is going on) is also displayed along with the results of other PHP session commands. For our purposes, however, it is useful because it shows you exactly what is happening and what PHP functions reference session information. The output of the above Web page might look something like this:
  Session Information

  Session Name: PHPSESSID
  Session ID : 6dbde574edc4b2d7be02727e048a382f
  Session Module: files
  Session Path : /tmp
  Session Encode: Username|s:13:"Vincent Danen";


  Welcome back, Vincent Danen!


This gives us a few vital pieces of information. Most of this can also be configured in your /etc/php.ini file, or wherever the php.ini file is located, so this information will change depending on how you configure PHP.

In the above code, the Session Name is the cookie name. You can change this from the default PHPSESSID in php.ini by setting the value of session.name. You can also use the session_name() function to change the name of the session ID, but you must do so before any output is sent to the browser and before the session itself is started. It might be a good idea to make the cookie name unique to your Web site.

The Session ID is a unique alphanumeric identifier for the session itself. This number will always be different. PHP will create a random ID string, but you can also create your own using the session_id() function. This should be unique for every session you make, so if you decide to create your own session ID, you must ensure that it is unique.

The Session Module will always be files. Currently this is the only way for PHP to store session information. It stores it in the Session Path, which is by default the /tmp directory. You do not need to worry about security because the file containing the session information is readable and writable only by that particular user the Web server is running under. So, for instance, if you run the Apache server as the user apache and group apache, the file will only be readable and writable by the user apache. The filename itself will contain the session ID string. If users have read access to the contents of /tmp (which most local users with shell access will have), they will be able to hijack the session because they will know the session ID. I advise you to have a specific nonworld readable directory in which to store the session IDs. This can be accomplished by changing your php.ini file and changing the value of the session.save_path from /tmp to something like /var/php/session and having that directory be readable and writable only by the user that you’ve used to run your Web server (i.e., the user apache).

Finally, the Session Encode string contains the contents of the session save file. This is the contents of the cookie; it contains the username because you registered the username with the session using the session_register() function. It is from this string that your data is obtained.

After filling out the form once, if you browsed a few other pages and then returned to that page an hour or so later, you would see that the page still welcomed you by your name. This is because the session ID is stored in a cookie in your browser.

Using this, you can easily keep track of user logins by saving the session ID in a database like MySQL. By storing the session ID in the database along with any other information you wanted to keep (such as login time, username, etc.), you can use the session ID as the key to retrieve that information.

For instance, upon the session start, you can write the session ID to the database, along with the user's name and login time. Upon the session end (via a logout or cookie expiry), you can remove that entry from the database by using the old session ID number as the key to remove it. By using this method, you can also store a minimum of information in the cookie itself, which makes sense, from the user's perspective, for security reasons.

As you can see, working with sessions in PHP is not very difficult at all. You can combine it with some database access and information storage to create a working login system or shopping cart system for your Web site. Using PHP to store this information will be much faster than doing something similar in Perl and certainly much more efficient than embedding hidden tags in forms throughout the site code.

As a surfer yourself, you may have noticed the proliferation of cookie usage. Cookies were designed to help keep track of users, so the most efficient way for you to compete with your virtual neighbor's Web site is to make use of the same technology.
The authors and editors have taken care in preparation of the content contained herein but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for any damages. Always have a verified backup before making any changes.

About

Vincent Danen works on the Red Hat Security Response Team and lives in Canada. He has been writing about and developing on Linux for over 10 years and is a veteran Mac user.

Editor's Picks