Section 13.3. Sessions


13.3. Sessions

HTML and web servers by default don't keep track of information that was entered on a page when the client's browser loads another page. This makes doing anything that involves using the same information from a user on several pages difficult.

Sessions help solve this problem by maintaining data during a user's visit to your web site from page to page on your site. Each session can store many variables that are maintained throughout that session. The server keeps track of users' sessions by assigning them a unique session ID, generated by the server, when the session starts. This identifier is called the session identifier and must be sent to the server each time a page is requested once a session begins. Figure 13-7 illustrates the interaction between the client browser and web server for a session.

Figure 13-7. A typical session stores some information on both the client and server hard disks


Sessions are stored on the server. The session variables are stored in a file and are serialized. When a variable is serialized, it's written out to a file as its name, type, and value all in a sequential string. On a Unix-based server, this file is usually written out to a directory under the /tmp (temporary) filesystem.

PHP doesn't actually create a record for a session until a session variable has been assigned a value. That makes sense since without any values to manage, the session doesn't really do anything.


The browser sends the session ID to the server each time it requests a page. The browser can send the session ID to the server either through a cookie or as a URL parameter. The default is to use the cookie, but because it's possible for a user to turn off cookies in his browser preferences, we also discuss passing the session ID in the URL string.

13.3.1. Using Sessions

To start a session, place the session_start function at the beginning of your PHP script before you can store or access any data during in the session. The session_start function, used in Example 13-10, needs to execute before any other header calls or other output is sent to the browser; otherwise, your session may not work properly.

Example 13-10. Simply starting a session

 <?php     session_start(); ?> 

First, we'll discuss the way variables used to be assigned to a session, since you may see this in code you get off the Web. The old school way is to use the session_register function, shown in Example 13-11. Don't use this method in your code, as it will cause an error.

Example 13-11. Registering a variable with session_register

 <?php //DON'T USE THIS APPROACH session_start(); session_register("hello"); $hello = "Hello World"; ?> 

Once the variable is bound like this in a PHP script, any changes to the variable are stored in the session. If the session isn't already started, the session_register command automatically starts it. Modern PHP interpreters return a warning with this code:

 Warning: Unknown(): Your script possibly relies on a session side-effect which existed until PHP 4.2.3. Please be advised that the session extension does not consider global variables as a source of data, unless register_globals is enabled. You can disable this functionality and this warning by setting session.bug_compat_42 or session.bug_compat_warn to off, respectively. in Unknown on line 0 

The correct way is to store and access session variables by the $_SESSION global variable with the name of the variable supplied within brackets. Assigning a new variable to the $_SESSION global automatically adds it to the session. The session must be started before you can access the session variables.

The use of session_register is considered to be less secure than using $_SESSION because of the possibility of a malicious user sending a value as a GET parameter with the same name as a registered session variable. For example, an attacker could send a bogus value for $username and make your PHP script believe a user is logged in who really didn't pass authentication.


For instance, Example 13-12 registers the same variable.

Example 13-12. Registering a variable by including it in $_SESSION

 <?php     session_start();     $_SESSION['hello'] = 'Hello World';     echo $_SESSION['hello']; ?> 

Now if the user was to follow a link to another page on your site that starts a session, the $_SESSION global variable contains a key called hello with the string value of Hello World, as shown in Example 13-13.

Example 13-13. Referencing a variable set on a prior page in the session

 <?php     session_start();     echo $_SESSION['hello']; ?> 

Therefore, the code in Example 13-13 displays this information, as shown in Figure 13-8.

Figure 13-8. The value set previously in the session is accessible


Either Examples 13-11 or 13-12 can be used to register the session variable before it's requested in Example 13-13.

13.3.2. Expanding Our Login Example

Most login systems use session variables to pass useful information around without having to re-retrieve them from the database. In Example 13-14, we're checking to see whether a user is valid, and then setting a few session variables.

Example 13-14. Checking to see whether a user is valid

 <?php session_start(); require_once('db_login.php'); require_once('DB.php'); if (empty($_SESSION['user_id'])) { DELETE THIS PAR AFTER MOVING THE FIGURE ANCHOR ---> if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) { header('WWW-Authenticate: Basic realm="Member Area"'); header("HTTP/1.0 401 Unauthorized"); echo "You must enter in a username and password combination!"; exit; } $connection = DB::connect("mysql://$db_username:$db_password@$db_host/$db_database"); if (DB::isError($connection)){ die ("Could not connect to the database: <br />". DB::errorMessage($connection)); } $username = mysql_real_escape_string($_SERVER['PHP_AUTH_USER']); $password = mysql_real_escape_string($_SERVER['PHP_AUTH_PW']); $query = "SELECT `user_id`, `username` FROM `users` WHERE `username`='".$username."' AND `password`=MD5('".$password."') LIMIT 1"; $result = $connection->query($query); if(!($row = $result->fetchRow(DB_FETCHMODE_ASSOC))) { header('WWW-Authenticate: Basic realm="Member Area"'); header("HTTP/1.0 401 Unauthorized"); echo "Your username and password combination was incorrect!"; exit; } $_SESSION['user_id'] = $row['user_id']; $_SESSION['username'] = $row['username']; } echo "You have successfully logged in as ".$_SESSION["username"]."."; ?> 

Example 13-14 displays Figure 13-9, followed by Figure 13-10, if you were successful.

Figure 13-9. The login prompt before entering our credentials


Figure 13-10. A successful login


The code first checks the session to see if the user_id session variable already has a value assigned to it. Subsequent pages can check for the session variables that were set at the end of Example 13-14 instead of doing another HTTP realm-based authentication and verifying that against the database.

If the session has the key user_id, you know the variable was set and you can continue without any further checking. However, email addresses and URLs are difficult to validate with 100% accuracy. Obviously, you'd mandate that an email address have an @ that is followed by some combination of letters, numbers, and the period. Lastly, there is a period followed by a two- to four-letter stringfor example, .nl, ca, com, edu, uk, or info. If you mandate certain parameters, you'll be more successful during validation.

When you're trying to validate a URL, you should check for the optional http://. After this, you want to see letters, numbers, or a dash, followed by a period, and then a two- to four-letter string as just described for email addresses.

13.3.3. Ending a Session

There are times when you want to end a session before the session times out. An example of this is when you provide a logout button or link on your page. The logout is actually done by ending the user's session. To end a session, use the session_destroy function. Of course, you must first start a session for it to make sense to destroy it.

Keep in mind that ending a session doesn't make the values from that session unavailable to the rest of the currently executing PHP page. Example 13-15 provides a simple script that both ends the session and makes the session values unavailable to the rest of the PHP script.

Example 13-15. Destroying a session

 <?php session_start(); // Do some miscellaneous work $_SESSION['username'] = 'Michele'; // Logout of the site session_destroy(); echo "At this point we can still see the value of username as ".$_SESSION['username']."<br />"; $_SESSION = array(); echo "Now the value of username is blank: ".$_SESSION['username']; ?> 

The code in Example 13-15 produces something like Figure 13-11.

Figure 13-11. Destroying a session and clearing out the values


When you destroy the session, the session data is deleted from the server's session files. To wipe out the values in the $_SESSION global variable, set it to an empty array.

Although you're using $_SESSION to destroy the values from the session, if you used session_register to add variables to a session, you need to use one of two functions to remove the values from the running script. The function session_unset removes all session variables while session_unregister removes only the variable name that's sent as a parameter.

We're going to address garbage collection and no, this isn't about when your garbage is collected at the curb, this is when a session is destroyed or times out.

13.3.3.1. Garbage collection

Garbage collection determines what happens to the contents of a session on the server after a session is destroyed or simply times out from inactivity. If the server didn't do periodic clean up of old sessions, they'd accumulate, endlessly wasting space, and creating clutter on the server. Garbage collection happens automatically and deletes all old session data.

PHP has a load-balancing feature for garbage collection, so that old session files aren't deleted for every session request. The default timeout for session files is 1440 seconds or 24 minutes. That probably doesn't seem like a lot of time if you have a very robust site, but PHP has commands that can delete garbage following parameters you set. A session file can be deleted after that timeout, but it could reside on the server longer, depending on the amount of sessions created.

The following PHP .ini variables deal with the garbage collector:

  • session.gc_maxlifetime

  • session.gc_probability

  • session.gc_divisor

In the above variables, gc equals garbage collector. If you have enough disk space on your server, you can set the session file timeout pretty long in order to preserve most or even all sessions until the browsers are closed. However, in many cases, the session needs to expire after a certain time, so you have to change the lifetime of the session cookie itself.

We'll discuss setting the session's timeout values so you get a better understanding of what you're going to need to do.

13.3.3.2. Setting a session's timeout

After a certain time period, it's reasonable to expect that a user's session should automatically log out, which is essentially an expiration period. PHP allows you to specifically set this duration. The best way to do this is to modify the .htaccess file.

The .htaccess file affects the HTML and PHP files in the same directory as the file. It allows you to make configuration changes without modifying Apache's configuration files. Any changes made in the .htaccess file also apply to files in subdirectories unless another .htaccess file is in a subdirectory. In Example 13-16, we're using the session.gc_maxlifetime variable.

Example 13-16. Session timeout

 <IfModule mod_php4.c>   php_value session.gc_maxlifetime "14400" </IfModule> 

The value that comes after sessions.gc_maxlifetime is in 100ths of a second, so, if you want a session timeout of 30 minutes, you would use a value of 18000.

The cookie path can be / or /directoryx if the cookie needs to be valid for a certain directory only. directoryx could be any directory or folder you have named specifically for the cookies.

As seen in Example 13-16, we have a session cookie with a custom-defined lifetime and a defined garbage collector timeout. This ensures that the current session data is available as long as the session cookie in the browser is valid. Authentication with Auth_HTTP is going to be discussed.




Learning PHP and MySQL
Learning PHP and MySQL
ISBN: 0596101104
EAN: 2147483647
Year: N/A
Pages: 135

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net