<?php
 
#    MySessions v1.0 - MySQL Based Sessions
 
#    Copyright (C) 2008  João Romão - iceburn.info
 
#
 
#    This program is free software: you can redistribute it and/or modify
 
#    it under the terms of the GNU General Public License as published by
 
#    the Free Software Foundation, either version 3 of the License, or
 
#    (at your option) any later version.
 
#
 
#    This program is distributed in the hope that it will be useful,
 
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
#    GNU General Public License for more details.
 
#
 
#    You should have received a copy of the GNU General Public License
 
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 
/**
 
 * MySessions v1.0
 
 * 
 
 * @package MySQL Based Sessions v1.0
 
 * @author João Romão (aka =IceBurn=)
 
 * @copyright João Romão - iceburn.info
 
 * @version 2008
 
 * @access public
 
 * 
 
 */
 
class MySessions
 
{
 
 
    /**
 
     * Define if the session_id should be always regenerated
 
     * 
 
     * Setting this to true will improve security, 
 
     * but also increase memory usage. 
 
     */
 
    const always_regenerate = true;
 
 
    /**
 
     * use: mydomain.com or leave blank OR .mydomain.com to keep sessions between sub-domains.
 
     * @var string
 
     */
 
    public $cookie_domain = '';
 
 
    /**
 
     *  usually '/' it's just fine
 
     * @var string
 
     */
 
    public $cookie_path = '/';
 
 
    /**
 
     * Sessions lifetime in seconds
 
     * @var int
 
     */
 
    public $sess_duration = 2300;
 
 
    /**
 
     * Table name to store sessions.
 
     * @var string
 
     */
 
    public $table_name = 'sessions';
 
 
    /**
 
     * Should sessions be passed to URL's? 0 = no / 1 = yes (not recomended!)
 
     * @var bool
 
     */
 
    public $use_trans_id = 0;
 
 
    /**
 
     * The name for the session (PHP's default is the ugly PHPSESSIONID)
 
     * @var string
 
     */
 
    public $session_name = 'sess';
 
 
 
    /**
 
     * sessions::__construct()
 
     * 
 
     * @access public
 
     * @return void
 
     */
 
    public function __construct() {
 
 
        /**
 
         * Comment the ini_set block if you get errors 
 
         * Errors happen when your host does not allow you to use ini_set function
 
         * Try use htaccess php_value/php_flag directive instead
 
         */
 
        ini_set('session.use_cookies', 1);
 
        ini_set('session.use_trans_sid', $this->use_trans_id);
 
        ini_set('session.use_only_cookies', 0);
 
        ini_set('session.gc_maxlifetime', $this->sess_duration);
 
        ini_set('session.hash_bits_per_character', 4);
 
        ini_set('session.name', $this->session_name);
 
 
        session_set_save_handler(array('MySessions', 'open'), array('MySessions', 'close'), 
 
                                 array('MySessions', 'read'), array('MySessions', 'write'), 
 
                                 array('MySessions', 'destroy'), array('MySessions', 'gc')) 
 
                                 or die('Could Not Set Session Handler!');
 
 
        session_set_cookie_params($this->sess_duration, $this->cookie_path, $this->cookie_domain);
 
 
    }
 
 
 
    /**
 
     * MySessions::session_start()
 
     * 
 
     * @return void
 
     */
 
    public function session_start() {
 
        session_start();
 
        $this->regenerate();
 
    }
 
 
 
    /**
 
     * MySessions::regenerate()
 
     * 
 
     * A session is regenerated either if specified in configurations or if somehow 
 
     * an invalid session_id is passed or if implicit.
 
     * @param integer $force
 
     * @return bool
 
     */
 
    public function regenerate($force = 0) {
 
 
        if (self::always_regenerate == true || strlen($this->protect(session_id())) != 32 || $force != 0) {
 
 
            $sid = session_id();
 
 
            session_regenerate_id(true);
 
 
            $nid = session_id();
 
 
            $qry = "UPDATE `" . $this->table_name . "` SET `id` = '" . $this->protect($nid) . "' WHERE id = '" . $this->protect($sid) . "';";
 
 
            return mysql_query($qry);
 
 
        }
 
 
    }
 
 
 
    /**
 
     * sessions::open()
 
     * 
 
     * @access public
 
     * @param mixed $sess_path
 
     * @param mixed $sess_name
 
     * @return bool
 
     */
 
    public function open($sess_path, $sess_name) {
 
        return true;
 
    }
 
 
    /**
 
     * sessions::close()
 
     * 
 
     * @access public
 
     * @return bool
 
     */
 
    public function close() {
 
        return true;
 
    }
 
 
 
    /**
 
     * sessions::read()
 
     * 
 
     * @access public
 
     * @param mixed $sess_id
 
     * @return string
 
     */
 
    public function read($sess_id) {
 
 
        $sql = "SELECT `data` FROM `" . $this->table_name . "` WHERE `id` = '" . $this->protect($sess_id) . "' ORDER BY `id` LIMIT 1;";
 
        $res = mysql_query($sql);
 
 
        if ($res) {
 
 
            if (mysql_num_rows($res) == 1) {
 
 
                $ret = mysql_result($res, 0, 0);
 
                mysql_free_result($res);
 
 
                return $ret;
 
 
            }
 
 
        }
 
 
        return;
 
    }
 
 
 
    /**
 
     * sessions::write()
 
     * 
 
     * @access public
 
     * @param mixed $sess_id
 
     * @param mixed $data
 
     * @return bool
 
     */
 
    public function write($sess_id, $data) {
 
        $sql = "INSERT INTO 
 
             `" . $this->table_name . "` (
 
              `id`, 
 
              `access`, 
 
              `data`
 
             ) VALUES (
 
              '" . $this->protect($sess_id) . "', 
 
              " . time() . ", 
 
              '" . mysql_real_escape_string($data) . "'
 
             ) ON DUPLICATE KEY UPDATE 
 
              `access` = " . time() . ",  
 
              `data`   = '" . mysql_real_escape_string($data) . "';";
 
 
        return mysql_query($sql) or die('Error Writing Session Data!');
 
    }
 
 
 
    /**
 
     * sessions::destroy()
 
     * 
 
     * Session destroy, useful for logouts
 
     * @access public
 
     * @param mixed $sess_id
 
     * @return bool
 
     */
 
    public function destroy($sess_id) {
 
 
        $_SESSION = array();
 
 
        if (isset($_COOKIE[$this->session_name])) {
 
            setcookie($this->session_name, '', (time() - 42000), $this->cookie_path, $this->cookie_domain);
 
        }
 
 
        $sql = "DELETE FROM `" . $this->table_name . "` WHERE `id` = '" . $this->protect($sess_id) . "';";
 
        return mysql_query($sql) or die('Error Destroing Session Data!');
 
    }
 
 
 
    /**
 
     * sessions::gc()
 
     * 
 
     * Garbage collector
 
     * @access public
 
     * @param mixed $sess_maxlifetime
 
     * @return bool
 
     */
 
    public function gc($sess_maxlifetime) {
 
 
        $old = (time() - $this->sess_duration);
 
 
        $sql = "DELETE FROM `" . $this->table_name . "` WHERE `access` < " . intval($old) . ";";
 
        $qry = mysql_query($sql);
 
 
        /**
 
         * You can comment the optimize part, and optimize your tables in an independent way.
 
         * In fact it's addvised that you do it, especially if you have a hight traffic load.
 
         */
 
        if (mysql_affected_rows() > 0) { $this->optimize(); }
 
 
        return true;
 
    }
 
 
 
    /**
 
     * sessions::optimize()
 
     * 
 
     * Usefull function for optimizing your sessions table.
 
     * @access public
 
     * @return bool
 
     */
 
    public function optimize() {
 
        return mysql_query('OPTIMIZE TABLE `' . $this->table_name . '`;');
 
    }
 
 
 
    /**
 
     * sessions::create_table()
 
     * 
 
     * You can call this function at the first run to create the necessary table.
 
     * No problem to call it after the table is created, but will increase memory.
 
     * If the table does not exist, the very first call to sessions will be stored 
 
     * as usual. It will always return true or die() if fail to create table.
 
     * @access public
 
     * @return bool
 
     */
 
    public function create_table() {
 
        $sql  = "CREATE TABLE IF NOT EXISTS `" . $this->table_name . "` (";
 
        $sql .= " `id` varchar(32) NOT NULL,";
 
        $sql .= " `access` int(10) unsigned default NULL,";
 
        $sql .= " `data` text,";
 
        $sql .= " PRIMARY KEY  (`id`) ";
 
        $sql .= ") ENGINE=MyISAM DEFAULT CHARSET=latin1;";
 
        $qry  = mysql_query($sql) or die('An Error Occorred: ' . mysql_error());
 
        $this->regenerate(1);
 
        return true;
 
    }
 
 
 
    /**
 
     * sessions::protect()
 
     * 
 
     * @access private
 
     * @param mixed $string
 
     * @return string
 
     */
 
    private function protect($string) {
 
        return mysql_real_escape_string(preg_replace('/[^a-v0-9]/i', '', $string));
 
    }
 
 
 
    /**
 
     * MySessions::debug()
 
     * 
 
     * Only for debugging reasons.
 
     * @return string
 
     */
 
    public function debug() {
 
        $ret  = var_dump($_COOKIE);
 
        $ret .= var_dump($_SESSION);
 
        return $ret;
 
    }
 
 
 
    /**
 
     * MySessions::__destruct()
 
     * 
 
     * @return void
 
     */
 
    public function __destruct() {
 
        session_write_close();
 
    }
 
 
 
} // End of class 'MySessions'
 
?>
 
 |