view resume | view portfolio | view code samples | contact | about

Login class(PHP4) | MySQL class(PHP5) | session handler(PHP5) | python pinger(Python) | Qmail popper(PHP4)

<?php
/***
* @note session handler::PHP5::session-class-php
* @author Stefan Antonowicz
* @link http://us2.php.net/manual/en/function.session-set-save-handler.php
*
* Database session handler
*
* This class overwrites the default session save functions for PHP, so we
* can write to the database rather than the filesystem

* @author Stefan Antonowicz <czgy94n02@sneakemail.com>

*
* This dbSession handler writes to a mysql table:
* CREATE TABLE `sessions` (
*  `sessionID` varchar(32) NOT NULL,
*  `session_data` longtext,
*  `session_time` int(11) NOT NULL DEFAULT '0',
*  `session_ip` varchar(32) DEFAULT NULL,
*  `session_status` enum('active','passive') DEFAULT NULL,
*  PRIMARY KEY (`sessionID`)
*) ENGINE=InnoDB DEFAULT CHARSET=latin1;
*
*  This file should also include the MySQL class, either through
*  autoloader or directly in controller
*/


class dbSession  {
    
/**
    * @access private
    * @var int
    *
    * Base lifetime of session
    */
    
private static $lifetime 0;
    
    
/**
    * @access private
    * @var string
    *
    * User defined Data Source Name (DSN) for mysql connection.  
    */
    
private static $dsn 'mysql://<username>:<password>@<host>/<dbname>';
    
    
/**
    * @access private
    * @var string
    *
    * User defined domain for any cookies to be set.  Set to .foo.com to 
    * allow cookies to be used across multiple servers and/or multiple
    * subdomains
    */
    
private static $cookie_domain '';
    
    
    
/**
    * Constructor
    *
    * The constructor uses the session_set_save_handler to overload the user-level session storage functions in PHP
    * Additionally, it calls session_start() after the session has been registered.  
    * All session_start( ) callouts sitewide MUST be in
    * the form of "new dbSession()" and NOT just "session_start()"
    *
    * @access public
    */
    
public function __construct( ) {        
        if( 
dbSession::$lifetime ) {
            
$this->lifetime dbSession::$lifetime;
        } else {
            
$this->lifetime ini_get'session.gc_maxlifetime' );
        }
        
        
session_set_save_handler(
            array( &
$this'open' ),
            array( &
$this'close' ),
            array( &
$this'read' ),
            array( &
$this'write' ),
            array( &
$this'destroy' ),
            array( &
$this'gc' )
        );
        
        
register_shutdown_function'session_write_close' );
        
$this->my = new MySQLdbSession::$dsn );
        
        
session_start( );
    }

    
/**
    * open
    *
    * As of PHP 5.0.5 the write  and close  handlers are called after object destruction and 
    * therefore cannot use objects or throw exceptions.  Not useful for current implementation
    *
    * @access public
    * @return bool  Always returns true (See Notes)    
    */
    
public function open$path$name ) {
        return( 
TRUE );
    }

    
/**
    * close
    *
    * As of PHP 5.0.5 the write  and close  handlers are called after object destruction and 
    * therefore cannot use objects or throw exceptions.  Not useful for current implementation
    *
    * @access public
    * @return bool  Always returns true (See Notes)    
    */
    
    
public function close( ) {
        return( 
TRUE );
    }

    
/**
    * read
    *
    * @access public
    * @return array  unserialized $_SESSION array stored in database
    *
    */
    
    
public function read$sid ) {
        
$this->my->sql "SELECT session_data FROM sessions WHERE sessionID = '$sid' AND session_time > " time();
        
$this->my->query( );
        
$fields mysql_fetch_assoc$this->my->result );
        return( 
$fields['session_data'] );
    }
    
    
/**
    * write
    * 
    * Stores unserialied array from $_SESSION as serialized string in database.  Serialization takes
    * place automagically by PHP session handlers. Additionally, creates new record if no record
    * currently exists
    *
    * @access public
    * @param $sid the php_session_id
    * @param $data the data to store
    */   
    
    
public function write$sid$data ) {
        
/** 
        * quick clean of ip so no one can poison the db via GLOBAL overload
        */
        
preg_match'/[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}/'$_SERVER['REMOTE_ADDR'], $match );
        
$ip sizeof$match ) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
        
        
$expiry time( ) + $this->lifetime;
        
        
$data mysql_real_escape_string$data );
           
        
$sql "INSERT INTO sessions (sessionID, session_data, session_time, session_ip)
                VALUES ('$sid', '$data', $expiry, '$ip') 
                ON DUPLICATE KEY UPDATE session_data='$data', session_time = '$expiry'"
;
        
        
$this->my->query$sql );;
    }
  
    
/**
    * destroy
    * 
    * Deletes session from database.  For now, also kills $_COOKIE containing session_name
    *
    * @access public    
    */   
    
    
public function destroy$sid ) {
        
$sql "DELETE FROM sessions WHERE sessionID = '$sid'";
        
$this->my->query$sql );
        
        if( isset( 
$_COOKIE[session_name()] ) ) {
            
setcookiesession_name( ), ''time()-42000'/' );
        }
    }
    
    
/**
    * gc 
    * 
    * Perform garbage collection, dependent on lifetime, gc_probability, 
    * and gc_divisor established in php.ini
    *
    * @access public
    * @return int        
    */
    
    
public function gc( ) {
        
$time time( ) - $this->lifetime;
        
$sql "DELETE FROM sessions WHERE session_time < $time";
        
$res $this->my->query$sql );
        return;
    }
    
    
    
/**
    * saveMessage 
    * 
    * Saves a message as an array - useful for passing messages
    * from one page to the other
    *
    * @access public
    * @param $msg array of messages      
    */
    
public static function saveMessage$msg  ) {
        if(! 
session_id( ) ) {
            return( 
FALSE );
        }
        
$_SESSION['message'] = $msg;
    }

    
/**
    * getMessageFromSession
    * 
    * returns an array of messages set by saveMessage, and unsets 
    * the variable
    *
    * @access public
    * @see saveMessage    
    */    
    
public static function getMessageFromSession( ) {
        if(! 
session_id( ) ) {
            return( 
FALSE );
        }
        if(! 
$_SESSION['message'] ) {
            return( 
FALSE );
        }
        
        
$msg $_SESSION['message'];
        unset( 
$_SESSION['message'] );
        return( 
$msg );
    }

    
/**
    * makeCookie
    * 
    * wrapper to set a cookie
    * @access public
    * @param $name the cookie name
    * @param $value the cookie value
    * @param $expiry when the cookie should expire. Leave as "0" for the cookie to expire on browser close
    * @param $path the path on the server that the cookie is valid.  Leave as "/" to allow the cookie to be
    *               accessed at all directory levels
    * @param $domain the domain that the cookie is set on.     
    */           
    
    
public static function makeCookie$name$value$expiry=0$path="/"$domain=''  ) {
        if(! 
$domain ) {
            
$domain dbSession::$cookie_domain;
        }
        
        
        
setcookie$name$value$expiry$path$domain );
    }
    
    
/**
    * getCookie
    * 
    * wrapper to retrieve a cookie
    * @access public
    * @param $name the cookie name
    * @param $serialized whether the cookie contains a serialized string, like a serialized array 
    */ 
    
    
public static function getCookie$name$serialized=FALSE ) {
        if(! 
$_COOKIE[$name] ) {
            return;
        }
        
$c $_COOKIE[$name];
        
        if( 
$serialized ) {
            
$c unserializestripslashes$c ) );
        }
        return( 
$c );
    }
  
    
/**
    * killCookie
    * 
    * wrapper to destroy a cookie
    * @access public
    * @param $name the cookie name
    * @param $path the path on the server that the cookie is valid.  Leave as "/" to allow the cookie to be
    *               accessed at all directory levels
    * @param $domain the domain that the cookie is set on.     
    */     
    
    
public static function killCookie$name$path="/"$domain=''  ) {
        if(! 
$domain ) {
            
$domain dbSession::$cookie_domain;
        }
        
dbSession::makeCookie$name''time()-3600$path$domain );
    }       
}
?>