php session management class with mySQL

By stefangabos on Aug 10, 2006

A class to handle sessions by using a mySQL database for session related data storage providing better security then the default session handler used by PHP. You don't need to modify a thing in your application - after instantianting the class just use sessions as you would normally. for the documentation go to http://stefangabos.blogspot.com/2006/08/zebra-php-framework-session-handler.html

<?php

/**
 *  A class to handle sessions by using a mySQL database for session related data storage providing better
 *  security then the default session handler used by PHP.
 *
 *  To prevent session hijacking, don't forget to use the {@link regenerate_id} method whenever you do a
 *  privilege change in your application
 *
 *  <i>Before usage, make sure you use the session_data.sql file from the install_sql folder to set up the table
 *  used by the class</i>
 *
 *  After instantiating the class, use sessions as you would normally
 *
 *  This class is an adaptation of John Herren's code from the "Trick out your session handler" article
 *  ({@link http://devzone.zend.com/node/view/id/141}) and Chris Shiflett's code from Chapter 8, Shared Hosting - Pg 78-80,
 *  of his book - "Essential PHP Security" ({@link http://phpsecurity.org/code/ch08-2})
 *
 *  <i>Note that the class assumes that there is an active connection to a mySQL database and it does not attempt to create
 *  one. This is due to the fact that, usually, there is a config file that holds the database connection related
 *  information and another class, or function that handles database connection. If this is not how you do it, you can
 *  easily adapt the code by putting the database connection related code in the "open" method of the class.</i>
 *
 *  The code is approx 9Kb in size but still heavily documented so you can easily understand every aspect of it
 *
 *  This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 2.5 License.
 *  To view a copy of this license, visit {@link http://creativecommons.org/licenses/by-nc-nd/2.5/} or send a letter to
 *  Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.
 *
 *  For more resources visit {@link http://stefangabos.blogspot.com}
 *
 *  @author     Stefan Gabos <ix@nivelzero.ro>
 *  @version    1.0 (last revision: August 05, 2006)
 *  @copyright  (c) 2006 Stefan Gabos
 *  @package    dbSession
*/

error_reporting(E_ALL);

class dbSession
{

    /**
     *  Constructor of class
     *
     *  @return void
     */
    function dbSession()
    {

        // get session lifetime
        $this->sessionLifetime = get_cfg_var("session.gc_maxlifetime");
        // register the new handler

        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');

        // start the session
        session_start();

    }

    /**
     *  Regenerates the session id.
     *
     *  <b>Call this method whenever you do a privilege change!</b>
     *
     *  @return void
     */
    function regenerate_id()
    {

        // saves the old session's id
        $oldSessionID = session_id();

        // regenerates the id
        // this function will create a new session, with a new id and containing the data from the old session
        // but will not delete the old session
        session_regenerate_id();

        // because the session_regenerate_id() function does not delete the old session,
        // we have to delete it manually
        $this->destroy($oldSessionID);

    }

    /**
     *  Get the number of online users
     *
     *  This is not 100% accurate. It depends on how often the garbage collector is run
     *
     *  @return integer     approximate number of users curently online
     */
    function get_users_online()
    {

        // counts the rows from the database
        $result = @mysql_fetch_assoc(@mysql_query("
            SELECT
                COUNT(session_id) as count
            FROM session_data
        "));

        // return the number of found rows
        return $result["count"];

    }

    /**
     *  Custom open() function
     *
     *  @access private
     */
    function open($save_path, $session_name)
    {

        return true;

    }

    /**
     *  Custom close() function
     *
     *  @access private
     */
    function close()
    {
        return true;
    }

    /**
     *  Custom read() function
     *
     *  @access private
     */
    function read($session_id)
    {

        // reads session data associated with the session id
        // but only if the HTTP_USER_AGENT is the same as the one who had previously written to this session
        // and if session has not expired
        $result = @mysql_query("
            SELECT
                session_data
            FROM
                session_data
            WHERE
                session_id = '".$session_id."' AND
                http_user_agent = '".$_SERVER["HTTP_USER_AGENT"]."' AND
                session_expire > '".time()."'
        ");

        // if anything was found
        if (is_resource($result) && mysql_num_rows($result) > 0) {

            // return found data
            $fields = mysql_fetch_assoc($result);
            // don't bother with the unserialization - PHP handles this automatically
            return $fields["session_data"];

        }

        // if there was an error return an epmty string - this HAS to be an empty string
        return "";

    }

    /**
     *  Custom write() function
     *
     *  @access private
     */
    function write($session_id, $session_data)
    {

        // first checks if there is a session with this id
        $result = @mysql_query("
            SELECT
                *
            FROM
                session_data
            WHERE
                session_id = '".$session_id."'
        ");

        // if there is
        if (mysql_num_rows($result) > 0) {

            // update the existing session's data
            // and set new expiry time
            $result = @mysql_query("
                UPDATE
                    session_data
                SET
                    session_data = '".$session_data."',
                    session_expire = '".(time() + $this->sessionLifetime)."'
                WHERE
                    session_id = '".$session_id."'
            ");

            // if anything happened
            if (mysql_affected_rows()) {

                // return true
                return true;

            }

        // if this session id is not in the database
        } else {

            // insert a new record
            $result = @mysql_query("
                INSERT INTO
                    session_data
                        (
                            session_id,
                            http_user_agent,
                            session_data,
                            session_expire
                        )
                    VALUES
                        (
                            '".$session_id."',
                            '".$_SERVER["HTTP_USER_AGENT"]."',
                            '".$session_data."',
                            '".(time() + $this->sessionLifetime)."'
                        )
            ");

            // if anything happened
            if (mysql_affected_rows()) {

                // return an empty string
                return "";

            }

        }

        // if something went wrong, return false
        return false;

    }

    /**
     *  Custom destroy() function
     *
     *  @access private
     */
    function destroy($session_id)
    {

        // deletes the current session id from the database
        $result = @mysql_query("
            DELETE FROM
                session_data
            WHERE
                session_id = '".$session_id."'
        ");

        // if anything happened
        if (mysql_affected_rows()) {

            // return true
            return true;

        }

        // if something went wrong, return false
        return false;

    }

    /**
     *  Custom gc() function (garbage collector)
     *
     *  @access private
     */
    function gc($maxlifetime)
    {

        // it deletes expired sessions from database
        $result = mysql_query("
            DELETE FROM
                session_data
            WHERE
                session_expire < '".(time() - $maxlifetime)."'
        ");

    }

}
?>

Comments

Sign in to comment.
wajidwarraich   -  Oct 05, 2011

please give me brief idea of php i am a starter of php

 Respond  
wajidwarraich   -  Oct 05, 2011

thats a good effort

 Respond  
wmatthews   -  Jun 23, 2011

This is great, exactly what I was looking for.

 Respond  
peterpowell   -  Aug 18, 2007

hi,

i will add a demo of this when i open my ftp next ;)

-pp

 Respond  
Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.