PHP Sessions


One of the most useful applications of cookies is the capability to create sessions, which truly allow you to overcome the state-less nature of the HTTP protocol. When working with sessions in PHP, you are given the capability to store variables (including arrays and classes) between script executions and recall them later. For this system to function, the Web server must be able to identify one Web browser from another, and this is where cookies play their role. Unlike my previous example of using cookies to identify a user, sessions do not actually store any significant information on the client machine. As with the car valet analogy, sessions work on the concept that each individual client browser is given a "ticket" (called a session ID), which is then presented to the Web server during every request. This session ID is then matched up with the relevant data and that data is again made available from within your PHP scripts.

Although sessions do offer a fair amount of security (because no sensitive information is being stored on the client browser itself), sessions are by no means completely secure. Because all the data for a particular user is tied to a single identifying string, it is possible (although unlikely) for a malicious user to hijack a session by guessing or otherwise acquiring a valid session ID. This may or may not be a serious issue, depending on the need for security on your website. It is generally considered good practice to develop a website under the assumption that a session will be hijacked; thus all critical pieces of data (credit card numbers, for example) should always be inaccessible if the session ID is compromised.

Basic Session Use

In this section, I discuss the basics of registering, unregistering, and working with session variables in PHP. It is important to note that manipulation of session variables using functions being introduced here such as session_register(), session_unregister(), and session_is_registered() should be used only if you have the register_globals PHP directive activated. If this directive is not activated (recommended), then all session variables must be manipulated using the $_SESSION superglobal array.

Starting a Session

There are three primary ways to create a session within PHP. The first method is to directly order PHP to begin a session by using the session_start() function. This function takes no parameters and has no return value. When this function is called, any variables that are associated this session will be reconstructed. This can also be accomplished by using the session_readonly() function, the second approach, which is used in place of the session_start() function. When this alternative is used, the session variables will all be re-created; however, any changes made to those variables will not be saved when the script terminates.

NOTE

In PHP, sessions work only with variables within the global scope. This means that to register a variable from a function, that variable must be declared global using the global statement. Likewise, PHP also reconstructs only variables within the global scope.


As I said, there are three ways to start a session within a PHP script. The third is to register a variable using the session_register() function.

Registering Session Variables

When registering a session variable, there are two methods of doing so. The first is to use the session_register() function. The syntax for this function is as follows:

 session_register($var_name [, $next_varname [, ...]]) 

$var_name (as well as any other additional parameters) are strings (or arrays of strings) representing the variable to store in the session. This function returns a Boolean true if all the variables provided were stored successfully, or it returns false on failure. Because the session_register() function does begin a session if it does not already exist, be aware that all calls to session_register() must be completed before any output is sent to the browser. Thus, although it is possible to begin a session using this function, it is better practice to manually begin a session using session_start() or similar facility first.

When you are working with session variables, there are some things that must be considered for things to work properly. To save you the time of finding them all out yourself, I will take a moment to explain these little details.

One of the most common mistakes for users when first working with PHP sessions is to automatically assume that the parameters passed to it are the actual variables to store in the session. However, session_register() accepts only strings representing the name of the variable to store in the session. This is most clearly illustrated by the following snippet (see Listing 6.7):

Listing 6.7. Using the session_register() Function
 <?php     $myvar = "This is my variable to store in the session";     $myvar_name = "myvar";     session_register($myvar_name); ?> 

When this code is executed, what is stored in the session? As you recall, the $myvar variable will be registered, not $myvar_name. If you are still confused, let me explain further. I have created two variables: $myvar, which is the actual value I'd like to save in the session, and $myvar_name. When the session_register() function is executed, PHP will attempt to store into the session the variable whose name is stored into the $myvar_name variable (not the $myvar_name variable itself). Because this variable has a value of myvar, the $myvar variable will be stored into the session.

For those who would rather not (or cannot, if the register_globals directive is disabled) use the session_register() function for working with session variables, PHP also provides the superglobal $_SESSION array. During the course of any session, the $_SESSION variable can be accessed and manipulated in the same manner as if the session_register() had been used. For instance, if you wanted to store the contents of $myvar from my previous example in a session using the superglobal method, the following would work:

 $_SESSION['myvar'] = $myvar; 

When you use this method to work with session variables, the session_register() function should not be used. Also, unlike when you work with the session_register() function, a session will not automatically be created by storing a variable in the $_SESSION superglobal. Hence, it is important that you explicitly begin a session prior to working with the $_SESSION superglobal.

Unregistering Session Variables

There are times (for instance, when a user logs out) when it is necessary to remove session variables. This can be done by destroying the entire session or by removing only certain session variables. To remove certain variables, you could either use the unset statement to remove the entry from the $_SESSION superglobal or use the session_unregister() PHP function. The syntax of the session_unregister() function is as shown next:

 session_unregister($name) 

Like its counterpart, session_register(), session_unregister() takes a string $name representing the global variable name to remove from the stored session variables. This function returns a Boolean true if the variable was removed successfully or returns false if the variable didn't exist.

Destroying Sessions

If you would like to destroy all the session variables (as well as the entire session), the session_destroy() function is used. Accepting no parameters, this function will destroy any cookies and data associated with the active session.

Working with Session Variables

Another possible need when working with sessions is to determine whether a session variable has been registered. This can be accomplished by using the isset statement to check for the existence of the proper key in the $_SESSION superglobal or by using the session_is_registered() function:

 session_is_registered($name) 

$name is a string representing the name of the session variable to check for. This function returns a Boolean TRue if the variable is registered or returns false if it is not.

To really demonstrate how sessions work in PHP, first we will need a situation where user-specific data must be saved across server requests. One ideal example with these sorts of requirements is an online shopping cart. For example, assume that all the functionality of the shopping cart script has been wrapped into a single PHP class called ShoppingCart. In this situation, for every individual shopper, an instance of the shopping cart is created only once and registered as a session variable by storing it in the $_SESSION superglobal. For each subsequent request, that instance (and all its data) is then re-created by PHP. Listing 6.8 illustrates the implementation of such a shopping cart system:

Listing 6.8. A Shopping Cart Class Example in PHP
 ShoppingCart.class.php <?php class ShoppingCart {         private $cart;         function __construct() {             $this->cart = array();         }         public function addItem($id, $name, $cost) {             foreach($this->cart as $key=>$items) {                 if($items['id'] == $id) {                     $this->cart[$key]['quantity']++;                     return;                 }             }             $this->cart[] = array('id' => $id,                                   'name' => $name,                                   'cost' => $cost,                                   'quantity' => 1);         }         public function delItem($id) {             foreach($this->cart as $key => $items) {                 if($items['id'] == $id)                     if($items['quantity'] > 1) {                         $this->cart[$key]['quantity']--;                     } else {                         unset($this->cart[$key]);                     }                     return true;                 }             }             return false;         }         public function getCart() {             return $this->cart;         }         public function clearCart() {             $this->cart = array();         } } ?> Listing6_8.php <?php     require_once("ShoppingCart.class.php");         session_start();         if(!isset($_SESSION['cart']) || !is_object($_SESSION['cart'])) {                $_SESSION['cart'] = new ShoppingCart();                 /* Add a book to the shopping cart (item #43 for $49.95) */                $_SESSION['cart']->addItem(43, "Book: PHP Unleashed", 49.95);         } ?> 

Although PHP has no problem using instances of objects as session variables, unlike any other data type in PHP, for an object to be re-created from a session, the initial class must be defined in the PHP script. This means that the ShoppingCart class definition itself must be included in the script for the $_SESSION['cart'] variable to be properly re-created.

Session Propagation

Now that you have an understanding of how sessions work from a function perspective, let's examine what types of practices are necessary for your sessions to function properly. As you know, individual sessions are identified by PHP through the use of a session ID, which is usually stored on the client machine in the form of an HTTP cookie. When cookie support is not available, this session ID must be propagated through the URL itself. To facilitate this, PHP provides the SID constant, which contains the current session ID name and value in the following format:

 <session name>=<session id> 

Because there are times when the format provided by the SID constant may not be desirable (as you'll see when propagating the session through an HTML form), PHP also provides two functions, session_name() and session_id(), which return the session name and its associated session ID, respectively. Regardless of the method used, the session ID must be used anytime a URL is provided that links to a nonexternal resource. For instance, for cases where a hyperlink is used, usually the SID constant works beautifully:

 <A HREF="checkout.php?<?php echo SID; ?>">Proceed to checkout</A> 

On the other hand, when working with HTML forms in general, the session ID is propagated through the use of a hidden form element. For situations such as this, the session_name() and session_id() functions must be used to fill in the appropriate values:

 <FORM ACTION="order.php" METHOD=GET> <INPUT TYPE="hidden" NAME="<?php echo session_name(); ?>"                        VALUE="<?php echo session_id(); ?>"> <!-- The remainder of the form HTML code //--> </FORM> 

It is very important to realize when propagating the session ID that it must be done only when the URL resides on your local Web server. To avoid negative security implications, at no time should the session ID be passed to an external URL.

As you may be thinking already, attempting to ensure that every single possible URL in your HTML documents is correctly propagating the session ID could quickly become an incredibly painful task. In most cases, URLs can be rewritten automatically by enabling transparent session ID propagation by enabling the session.use_trans_sid configuration directive. When transparent session propagation is enabled, PHP will attempt to automatically append the session ID to the appropriate HTML tags.

NOTE

PHP determines what URLs are rewritten in the output being sent to the browser by the url_rewriter.tags configuration directive. This directive is a comma-separated list of values in the following format:

 <HTML tag>=<Attribute> 

<HTML tag> is the HTML tag that should be processed, and <Attribute> is the attribute of that HTML tag that contains the URL to rewrite. For your reference, the default value for the url_rewriter.tags directive is as follows:

[View full width]

url_rewriter.tags = "a=href,area=href,frame=src,input=src ,form=fakeentry"


When using transparent session ID propagation, PHP will rewrite relative URLs only for security reasons. Even though http://www.coggeshall.org/index.php and /index.php may be the same resource, PHP will append the session ID only to the latter of the two. This is to prevent the already mentioned security risk of passing a valid session ID to an external website. Hence, when using transparent session ID propagation, it is important to ensure that all your nonexternal URLs are written using the accepted relative URL format.



PHP 5 Unleashed
PHP 5 Unleashed
ISBN: 067232511X
EAN: 2147483647
Year: 2004
Pages: 257

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