View Single Post
  #1 (permalink)  
Old June 22nd, 2005, 10:57 AM
mlange mlange is offline
Registered User
 
Join Date: Jun 2005
Location: Zoetermeer, , Netherlands.
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
Default Chapter 15: usersession.phpm

After fixing most stuff in usersession.phpm and altering the system slightly I came with the class UserSession as described below. However I still experience problems with it: the session is only available in the current page, how do I "transport" it's data (userobject, dbhandle and such) to the next page?

Some of the maybe more interesting changes I have emphasized in bold

Code:
<?php
/* user object is in o_user.php */
require_once($_SERVER['DOCUMENT_ROOT'].'/objects/o_user.php');
class UserSession
{
    private $php_session_id;
    private $native_session_id;
    private $dbhandle;
    private $logged_in;
    private $user_id;
    private $userobject;
    private $session_timeout=600;
    private $session_lifespan=3600;

    public function __construct()
    {
        /* connect to the database */
        $this->dbhandle=pg_connect("host=localhost dbname=pg_php5 user=session_manager password=********");
        /* 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 - if one is - if it looks wrong we'll scrub it right away */
        $strUserAgent = $_SERVER["HTTP_USER_AGENT"];
        if(isset($_COOKIE["PHPSESSID"]))
        {
            /* security and age check */
            $this->php_session_id = $_COOKIE["PHPSESSID"];
            $stmt=sprintf("SELECT id FROM \"user_session\" WHERE 
                ascii_session_id = '%s' AND
                (now() - created < '%d seconds') AND
                user_agent= '%s' AND
                ((now() - last_impression) <= '%d seconds' OR
                last_impression IS NULL)",
                $this->php_session_id,
                $this->session_lifespan,
                $strUserAgent,
                $this->session_timeout);
            $result = pg_query($this->dbhandle,$stmt);
            if(pg_num_rows($result) == 0)
            {
                /* set failed flag */
                $failed = 1;
                /* delete from database, we do garbage cleanup at the same time */
                $delete_query=sprintf("DELETE FROM \"user_session\" WHERE
                (ascii_session_id = '%s') OR (now() - created) > '%d seconds'",
                    $this->php_session_id,
                    $this->session_lifespan);
                $result = pg_query($this->dbhandle, $delete_query);
                /* clean up stray session variables */
                $delete_query=sprintf("DELETE FROM \"session_variable\" WHERE session_id NOT IN (SELECT id FROM \"user_session\")");
                $result=pg_query($this->dbhandle,$delete_query);
                /* get rid of this one... this will force PHP to give us another */
                unset($_COOKIE["PHPSESSID"]);
            };
        };
        /* set the lifetime 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)
        {
            $update_query=sprintf("UPDATE \"user_session\" 
                SET last_impression = now() 
                WHERE id = %d",
                $this->native_session_id);
        };
    }

    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("CUser"))
            {
                return $this->userobject;
            }
            else
            {
                return (false);
            };
        }
        else
        {
            return (false);
        };
    }

    public function GetSessionIdentifier()
    {
           return($this->php_session_id);
    }

    public function Login($strUsername, $strPlainPassword)
    {
        if(class_exists("CUser"))
        {
            $this->userobject=new CUser($strUsername, $strPlainPassword, "dbhost", "5432", "database");
            $update_query=sprintf("UPDATE \"user_session\" SET
                logged_in = true,
                user_id = %d
                WHERE id = %d",
                $this->user_id,
                $this->native_session_id);
            $result=pg_query($this->dbhandle,$update_query);
        }
        else
        {
            return(false);
        }


    }

    public function LogOut()
    {
        if($this->logged_in == true)
        {
            $update_query=sprintf("UPDATE \"user_session\"
                SET logged_in = false,
                user_id = 0
                WHERE
                id = %d",
                $this->native_session_id);
            $result=pg_query($this->dbhandle,$update_query);
            $this->logged_in = false;
            $this->user_id = 0;
            return(true);
        }
        else
        {
            return(false);
        };
    }

    public function __get($nm)
    {
        $select_query=sprintf("SELECT variable_value FROM session_variable
            WHERE session_id = %d
            AND variable_name = '%s'",
            $this->native_session_id,
            $nm);
        $result = pg_query($this->dbhandle,$select_query);
        if(pg_num_rows($result) > 0)
        {
            $row=pg_fetch_array($result);
            return(unserialize($row["variable_value"]));
        }
        else
        {
            return(false);
        };
    }

    public function __set($nm, $val)
    {
        $strSer = serialize($val);
        $check_query=sprintf("SELECT id FROM session_variable WHERE
            session_id = %d
            AND variable_name = '%s'",
            $this->native_session_id,
            $nm);
        $result=pg_query($this->dbhandle,$check_query);
        if(pg_num_rows($result) > 0)
        {
            $data=pg_fetch_object($result);
            $stmt=sprintf("UPDATE session_variable SET variable_value='%s' WHERE id = %d",
                $strSer, $data->id);
        }
        else
        {
            $stmt=sprintf("INSERT INTO session_variable
                (session_id, variable_name, variable_value)
                VALUES
                (%d, '%s', '%s')",
                $this->native_session_id,
                $nm,
                $strSer);
        }
        $result=pg_query($this->dbhandle,$stmt);
    }

    private function _session_open_method($save_path, $session_name)
    {
        /* do nothing */
        return(true);
    }

    public function _session_close_method()
    {
           pg_close($this->dbhandle);
           return(true);
    }

    private function _session_read_method($id)
    {
        /* we use this to determine wheter or not our session actually exists. */
        $strUserAgent=$_SERVER["HTTP_USER_AGENT"];
        $this->php_session_id = $id;
        /* set failed flag to 1 for now */
        $failed = 1;
        /* see if this exists in the database or not */
        $select_query=sprintf("SELECT id, logged_in, user_id 
            FROM \"user_session\"
            WHERE ascii_session_id = '%s'",$id);
        $result=pg_query($this->dbhandle,$select_query);
        if(pg_num_rows($result) > 0)
        {
            $row=pg_fetch_array($result);
            $this->native_session_id = $row["id"];
            if($row["logged_in"] == "t")
            {
                $this->logged_in = true;
                $this->user_id = $row["user_id"];
            }
            else
            {
                $this->logged_in = false;
            };
        }
        else
        {
            $this->logged_in = false;
            /* we need to create an entry in the database */
            $insert_query=sprintf("INSERT INTO user_session
                (ascii_session_id, logged_in, user_id, created, user_agent)
                VALUES
                ('%s','%s',%d,now(),'%s')",
                $id, 'f', 0, $strUserAgent);
            $result=pg_query($this->dbhandle,$insert_query);

            $select_query=sprintf("SELECT id FROM \"user_session\" WHERE ascii_session_id = '%s'",
                $id);
            $result=pg_query($this->dbhandle,$select_query);
            $data=pg_fetch_object($result);
            $this->native_session_id = $data->id;
        };
        /* just return an empty string */
        return("");
    }

    public function _session_write_method($id,$sess_data)
    {
        return(true);
    }

    private function _session_destroy_method($id)
    {
        $delete_query=sprintf("DELETE FROM \"user_session\"
            WHERE ascii_session_id = '%s'",$id);
        $result=pg_query($this->dbhandle,$delete_query);
        return($result);
    }

    private function _session_gc_method($maxlifetime)
    {
        return(true);
    }
}


?>
if for example I created a script test.php with this very rough and sloppy code:
Code:
<?php
    $user=$_POST['username'];
    $pass=$_POST['password'];

    $Session=& new UserSession();
    $Session->Impress();
    $Session->LogIn($user,$pass);

    /* yay, we now have a user object, you may check it, but this goes well, on to the following page... we have a session going on, don't we? */
?>
<form method="post" action="nextpage.php">
   <input type="submit">
</form>
okay, a nice file... we have our session object and we need the next page, that's where sessions come in handy, so we pressed the button and according to our form nextpage.php will be fired:
Code:
<?php
    /* code to insert usersession.phpm here */

    print_r($Session); /* you'll see: $Session is unknown */
    print_r($_SESSION); /* no $_SESSION either, where did our object go? */

    /* create a new one? */
    $Session = & new Session();
    print_r($Session); /* oh my, we have no database connection, this is a new object, so that is expected... */
?>
as you can imagine, the UserSession object would only be really useful if we can pass it to serveral pages.

We are running PHP5, so RegisterGlobals is off (default, and good riddance, we use $_SERVER, $_SESSION, $_COOKIE, $_POST etc etc etc as is good practice)

It is no use to try session_start(), as session is already started in the constructor, however, we need to pass $Session on to the next page. Of course this could be handled by posting $Session in the form as well, but that would be a bit ugly, as Sessions should not have to be posted along...

If someone knows a good way to fix this, I am very curious...