View Single Post
  #9 (permalink)  
Old January 4th, 2007, 11:11 AM
carlolsen carlolsen is offline
Authorized User
 
Join Date: Jan 2004
Location: Des Moines, IA, USA.
Posts: 20
Thanks: 0
Thanked 0 Times in 0 Posts
Default

This seems to be working well. I did store the id returned in the constructor and store it in the native_session_id global variable. This seems to be missing from the original code. Other than than, it's pretty much a straight conversion to PHP 5 and MySQL 5 (using the mysqli extensions).

Code:
<?php
require_once('users/class.UserDatabase.php');
final class UserSession extends UserDatabase
{
    private $php_session_id;
    private $native_session_id;
    private $dbhandle;
    private $logged_in;
    private $user_id;
    private $session_timeout = 600;            # 10 minute inactivity timeout
    private $session_lifespan = 3600;        # 1 hour session duration

    public function __construct()
    {
        # Connect to database
        parent::__construct();
        # Set up the handler
        session_set_save_handler(
            array(&$this, '_session_open_method'),
            array(&$this, '_session_close_method'),
            array(&$this, '_session_read_method'),
            array(&$this, '_session_write_method'),
            array(&$this, '_session_destroy_method'),
            array(&$this, '_session_gc_method')
        );
        # Check the cookie passed - if one is - if it looks wrong we'll scrub it right away
        $strUserAgent = $_SERVER["HTTP_USER_AGENT"];
        $strUserIP = $_SERVER["REMOTE_ADDR"];
        if (isset($_COOKIE["PHPSESSID"]))
        {
            # Security and age check
            $this->php_session_id = $_COOKIE["PHPSESSID"];
            $sql = "SELECT id FROM user_session WHERE ascii_session_id = '" . $this->php_session_id . "' AND DATE_SUB(NOW(), INTERVAL " . $this->session_lifespan . " SECOND) < created AND user_agent = '" . $strUserAgent . "' AND user_ip = '" . $strUserIP . "' AND DATE_SUB(now(), INTERVAL " . $this->session_timeout . " SECOND) <= last_impression OR last_impression IS NULL";
            $rows = 0;
            if($stmt = $this->conn->prepare($sql))
            {
                $stmt->execute();
                $stmt->bind_result($id);
                while($stmt->fetch())
                {
                    $this->native_session_id = $id;
                    $rows++;
                }
                $stmt->free_result();
                $stmt->close();
            }
            if($rows == 0)
            {
                # Set failed flag
                $failed = 1;
                # Delete from database - we do garbage cleanup at the same time
                $sql = "DELETE FROM user_session WHERE (ascii_session_id = '" . $this->php_session_id . "') OR DATE_SUB(now(), INTERVAL " . $this->session_lifespan . " SECOND) > created";
                if($stmt_user = $this->conn->prepare($sql))
                {
                    $stmt_user->execute();
                    $stmt_user->close();
                }
                # Clean up stray session variables
                $sql = "DELETE FROM session_variable WHERE session_id NOT IN (SELECT id FROM user_session)";
                if($stmt_vars = $this->conn->prepare($sql))
                {
                    $stmt_vars->execute();
                    $stmt_vars->close();
                }
                # Get rid of this one... this will force PHP to give us another
                unset($_COOKIE["PHPSESSID"]);
            }
        }
        # Set the life time for the cookie
        session_set_cookie_params($this->session_lifespan);
        # Call the session_start method to get things started
        session_start();
    }
    public function Impress()
    {
        if($this->native_session_id)
        {
            $sql = "UPDATE user_session SET last_impression = now() WHERE id = " . $this->native_session_id;
            if($stmt = $this->conn->prepare($sql))
            {
                $stmt->execute();
                $stmt->close();
            }
        }
    }
    public function IsLoggedIn()
    {
        return($this->logged_in);
    }
    public function GetUserID()
    {
        if($this->logged_in)
        {
            return($this->user_id);
        }
        else 
        {
            return(false);
        }
    }
    public function GetUserObject()
    {
        if($this->logged_in)
        {
            if(class_exists("User"))
            {
                $objUser = new User($this->user_id);
                return($objUser);
            }
            else 
            {
                return(false);
            }
        }
    }
    public function GetSessionIdentifier()
    {
        return($this->php_session_id);
    }
    public function Login($strUsername, $strPlainPassword)
    {
        $strMD5Password = md5($strPlainPassword);
        $sql = "SELECT user_id FROM user_credentials WHERE susername = '" . $strUsername . "' AND spassword = '" . $strMD5Password . "'";
        $rows = 0;
        if($stmt = $this->conn->prepare($sql))
        {
            $stmt->execute();
            $stmt->bind_result($uid);
            while($stmt->fetch())
            {
                $this->user_id = $uid;
                $rows++;
            }
            $stmt->free_result;
            $stmt->close();
        }
        if($rows > 0)
        {
            $this->logged_in = true;
            $sql = "UPDATE user_session SET logged_in = true, user_id = " . $this->user_id . " WHERE id = " . $this->native_session_id;
            if($stmt_user = $this->conn->prepare($sql))
            {
                $stmt_user->execute();
                $stmt_user->close();
            }
            return(true);
        }
        else 
        {
            return(false);
        }
    }
    public function LogOut()
    {
        if($this->logged_in == true)
        {
            $sql = "UPDATE user_session SET logged_in = false, user_id = 0 WHERE id = " . $this->native_session_id;
            if($stmt = $this->conn->prepare($sql))
            {
                $stmt->execute();
                $stmt->close();
            }
            $this->logged_in = false;
            return(true);
        }
        else 
        {
            return(false);
        }
    }
    public function __get($nm)
    {
        $sql = "SELECT variable_value FROM session_variable WHERE session_id = " . $this->native_session_id . " AND variable_name = '" . $nm . "'";
        $rows = 0;
        if($stmt = $this->conn->prepare($sql))
        {
            $stmt->execute();
            $stmt->bind_result($value);
            while($stmt->fetch())
            {
                $variable_value = $value;
                $rows++;
            }
            $stmt->free_result();
            $stmt->close();
        }
        if ($rows > 0)
        {
            return(unserialize($variable_value));
        }
        else 
        {
            return(false);
        }
    }
    public function __set($nm, $val)
    {
        $strSer = serialize($val);
        $sql = "INSERT INTO session_variable (session_id, variable_name, variable_value) VALUES (" . $this->native_session_id . ",'" . $nm . "','" . $strSer . "')";
        if($stmt = $this->conn->prepare($sql))
        {
            $stmt->execute();
            $stmt->close();
        }
    }
    private function _session_open_method($save_path, $session_name)
    {
        # Do nothing
        return(true);
    }
    private function _session_close_method()
    {
        parent::__destruct();
        return(true);
    }
    private function _session_read_method($id)
    {
        # We use this to determine whether or not our session actually exists
        $strUserAgent = $_SERVER["HTTP_USER_AGENT"];
        $strUserIP = $_SERVER['REMOTE_ADDR'];
        $this->php_session_id = $id;
        # Set failed flag to 1 for now
        $failed = 1;
        # See if this exists in the database or not
        $sql = "SELECT id, logged_in, user_id FROM user_session WHERE ascii_session_id = '" . $id . "'";
        $rows = 0;
        if($stmt = $this->conn->prepare($sql))
        {
            $stmt->execute();
            $stmt->bind_result($sid, $logged_in, $user_id);
            while($stmt->fetch())
            {
                $this->native_session_id = $sid;
                if($logged_in == true)
                {
                    $this->logged_in = true;
                    $this->user_id = $user_id;
                }
                else 
                {
                    $this->logged_in = false;
                }
                $rows++;
            }
            $stmt->free_result();
            $stmt->close();
        }
        if($rows == 0) 
        {
            $this->logged_in = false;
            # We need to create an entry in the databse
            $sql = "INSERT INTO user_session (ascii_session_id, logged_in, user_id, created, user_agent, user_ip) VALUES ('" . $id . "',false,0,now(),'" . $strUserAgent . "','" . $strUserIP . "')";
            if($stmt_user = $this->conn->prepare($sql))
            {
                $stmt_user->execute();
                $stmt_user->close();
            }
            # Now get the true id
            $sql = "SELECT id FROM user_session WHERE ascii_session_id = '" . $id . "'";
            if($stmt_id = $this->conn->prepare($sql))
            {
                $stmt_id->execute();
                $stmt_id->bind_result($session_id);
                $stmt_id->fetch();
                $this->native_session_id = $session_id;
                $stmt_id->free_result();
                $stmt_id->close();
            }
        }
        else 
        {
            return("");
        }
    }
    private function _session_write_method($id, $sess_data)
    {
        return($true);
    }
    private function _session_destroy_method($id)
    {
        $sql = "DELETE FROM user_session WHERE ascii_session_id = '" . $id . "'";
        if($stmt = $this->conn->prepare($sql))
        {
            $stmt->execute();
            $stmt->close();
            return(true);
        }
        else
        {
            return(false);
        }
    }
    private function _session_gc_method($maxlifetime)
    {
        return($true);
    }
}
?>