Home arrow PHP arrow Page 2 - Using Session Handling Objects to Maintain the State of Applications with PHP Sessions

A procedural implementation of the “session_set_save_handler()” function - PHP

Here you have it. The tutorial that you were waiting for! Welcome to the concluding part of the series “Maintaining the state of applications with PHP sessions.” In several tutorials, this series goes through the key points of managing sessions in PHP, and explores some of their most advanced features, such as developing user-defined session storage modules and using session handling objects.

TABLE OF CONTENTS:
  1. Using Session Handling Objects to Maintain the State of Applications with PHP Sessions
  2. A procedural implementation of the “session_set_save_handler()” function
  3. Developing an object-oriented session management module
  4. Coding the session handling class
By: Alejandro Gervasio
Rating: starstarstarstarstar / 27
May 10, 2006

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Before I proceed further in the creation of a session handling class, let’s remind ourselves how the “session_set_save_handler()” can be fed with the proper callback functions, in order to develop a session storage module that uses a MySQL database table for saving and reading session data. As you’ll recall, the signatures for these functions were the following:

// define 'openSession()' function
function openSession($sessionPath,$sessionName){
    return true;
}
// define 'closeSession()' function
function closeSession(){
    return true;
}
// define 'readSession()' method
function readSession($sessionId){
    global $db;
    // escape session ID
    if(!get_magic_quotes_gpc()){
        $sessionId=mysql_real_escape_string($sessionId);
    }
    $result=$db->query("SELECT sessiondata FROM sessions WHERE
sessionid='$sessionId' AND expiry > NOW()");
    if($result->countRows()>0){
        $row=$result->fetchRow();
        return $row['sessiondata'];
    }
    // return empty string
    return "";
}
// define 'writeSession()' function
function writeSession($sessionId,$sessionData){
    global $db;
    $expiry=time()+get_cfg_var('session.gc_maxlifetime')-1;
    // escape session ID & session data
    if(!get_magic_quotes_gpc()){
        $sessionId=mysql_real_escape_string($sessionId);
    }
    $result=$db->query("SELECT sessionid FROM sessions WHERE
sessionid='$sessionId'");
    // check if a new session must be stored or an existing one
must be updated 
    ($result->countRows()>0)?$db->query("UPDATE sessions SET
sessionid='$sessionId',expiry='$expiry',sessiondata=
'$sessionData' WHERE sessionid='$sessionId'"):$db->query("INSERT
INTO sessions (sessionid,expiry,sessiondata) VALUES
('$sessionId','$expiry','$sessionData')");
    return true;
}
// define 'destroySession()' function
function destroySession($sessionId){
    global $db;
    // escape session ID
    if(!get_magic_quotes_gpc()){
        $sessionId=mysql_real_escape_string($sessionId);
    }
    $db->query("DELETE FROM sessions WHERE sessionid='$sessionId'");
    return true;
}
// define 'gcSession()' function
function gcSession($maxlifetime){
    global $db;
    $db->query("DELETE FROM sessions WHERE expiry < NOW()");
    return true;
}

After listing the corresponding callback functions, which must be registered by the “session_set_save_handler()” function, here is the signature of the MySQL processing classes used within some of these functions:

class MySQL {
    var $conId; // connection identifier
    var $host; // MySQL host
    var $user; // MySQL username
    var $password; // MySQL password
    var $database; // MySQL database
    // constructor
    function MySQL($options=array()){
        // validate incoming parameters
        if(count($options)>0){
            foreach($options as $parameter=>$value){
                if(empty($value)){
                    trigger_error('Invalid parameter
'.$parameter,E_USER_ERROR);
                }
                $this->{$parameter}=$value;
            }
            // connect to MySQL
            $this->connectDB();
        }
        else {
            trigger_error('No connection parameters were
provided',E_USER_ERROR);
        }
    }
    // connect to MYSQL server and select database
    function connectDB(){
        if(!$this->conId=mysql_connect($this->host,$this-
>user,$this->password)){
            trigger_error('Error connecting to the
server',E_USER_ERROR);
        }
        if(!mysql_select_db($this->database,$this->conId)){
            trigger_error('Error selecting
database',E_USER_ERROR);
        }
    }
    // perform query
    function query($query){
        if(!$this->result=mysql_query($query,$this->conId)){
            trigger_error('Error performing query
'.$query,E_USER_ERROR);
        }
        // return new Result object
        return new Result($this,$this->result); 
    }
}

class Result {
    var $mysql; // instance of MySQL object
    var $result; // result set
    function Result(&$mysql,$result){
        $this->mysql=&$mysql;
        $this->result=$result;
    }
    // fetch row
    function fetchRow(){
        return mysql_fetch_array($this->result,MYSQL_ASSOC);
    }
    // count rows
    function countRows(){
        if(!$rows=mysql_num_rows($this->result)){
            return false;
        }
        return $rows;
    }
    // count affected rows
    function countAffectedRows(){
        if(!$rows=mysql_affected_rows($this->mysql->conId)){
            trigger_error('Error counting affected
rows',E_USER_ERROR);
        }
        return $rows;
    }
    // get ID from last inserted row
    function getInsertID(){
        if(!$id=mysql_insert_id($this->mysql->conId)){
            trigger_error('Error getting ID',E_USER_ERROR);
        }
        return $id;
    }
    // seek row
    function seekRow($row=0){
        if(!mysql_data_seek($this->result,$row)){
            trigger_error('Error seeking data',E_USER_ERROR);
        }
    }
    function getQueryResource(){
        return $this->result;
    }
}

Right, at this point the MySQL-driven session storage module is close to completion. All I have to do now is call the “session_set_save_handler()” function, passing as arguments the callback functions that you saw before. This operation is performed by the following code snippet:

// include classes
require_once 'mysqlclass.php';
require_once 'resultclass.php';
// connect to MySQL
$db=&new MySQL(array
('host'=>'localhost','user'=>'user','password'=>'password',
'database'=>'database'));
// use 'session_set_save_handler function'
session_set_save_handler
('openSession','closeSession','readSession','writeSession',
'destroySession','gcSession');
session_start();
// register some session variables
$_SESSION['firstname']='John';
$_SESSION['lastname']='Doe';

As you can see, here I wrote a procedural script that utilizes the “session_set_save_handler()” function in conjunction with the respective callback functions defined before, in order to manage PHP sessions through a simple “sessions” MySQL database table. By following this approach, instead of using flat files (the default behavior of the PHP session management module), it’s possible to handle sessions in a more secure way. As you may have guessed, this benefit can be quite remarkable for Web applications that need to rely on an improved session handling mechanism, rather than simple flat files.

So far, the procedural method that I developed earlier may potentially fit the needs of an advanced PHP application that uses sessions to maintain its state between different HTTP requests. However, I’d like to show you how to use the same callback functions, this time transformed to the methods of a useful session handling class. Want to see how this is achieved? Fine, let’s jump to the next section.



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: