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)."'
");
}
}
?>