Wrox Programmer Forums
| Search | Today's Posts | Mark Forums Read
BOOK: Professional PHP 5 ISBN: 978-0-7645-7282-1
This is the forum to discuss the Wrox book Professional PHP5 by Ed Lecky-Thompson, Heow Eide-Goodman, Steven D. Nowicki, Alec Cove; ISBN: 9780764572821
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Professional PHP 5 ISBN: 978-0-7645-7282-1 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
  #1 (permalink)  
Old June 22nd, 2005, 10:57 AM
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...
  #2 (permalink)  
Old June 22nd, 2005, 11:01 AM
Registered User
 
Join Date: Jun 2005
Location: Zoetermeer, , Netherlands.
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I noticed a discrepancy:
$Session->LogIn(...) should be $Session->Login(...)


  #3 (permalink)  
Old June 22nd, 2005, 11:03 AM
richard.york's Avatar
Wrox Author
Points: 5,506, Level: 31
Points: 5,506, Level: 31 Points: 5,506, Level: 31 Points: 5,506, Level: 31
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Camby, IN, USA.
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
Default

Function names are case-insensitive in PHP, so that shouldn't matter.

Regards,
Rich

--
[http://www.smilingsouls.net]
Mail_IMAP: A PHP/C-Client/PEAR solution for webmail
Author: Beginning CSS: Cascading Style Sheets For Web Design
  #4 (permalink)  
Old July 7th, 2005, 05:39 PM
Registered User
 
Join Date: Jun 2005
Location: , , .
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I spent a bit of time this evening trying to resolve this problme on my machine. I am running php5 with mysql instead of the authors' beloved PostgreSQL. The following is the finalised code I have for dealing with sessions. It makes use of the PEAR DB as described in chapter 8.

The main stumbling block was the way the class updated the timestamps in the database. I have never used PGSQL, but the methods seemed to be inserting 'now()' to set a field to the current timestamp, as far as my experience goes my version of MySQL does not support this. On replacing this with date("YmdHis"), the page impression field is updated correctly in MySQL (of course you could just use the PHP built-in time() function and record that instead and change the cookie checking sql slightly).

Without this change the constructor was issuing a new session id every time as the statement it ran to check the cookie validity was failing due to the incorrect last_impression field. Now the class works as expected, maintaining the session and variables across pages.

One last thing I changed (as did the mlange) was the __set method, which now looks if a value has been set already then chooses to update or insert, otherwise we may end up with multiple rows with the same var name.

Here is the code...

<?php
require_once('class.Database.phpm');

  class UserSession {
    private $php_session_id;
    private $native_session_id;
    private $objDB;
    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
      try {
        $this->objDB = Database::instance();
      } catch (Exception $e) {
        echo $e->getMessage();
        exit(1);
      }

      # 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 = $GLOBALS["HTTP_USER_AGENT"];
      if ($_COOKIE["PHPSESSID"]) {
       # Security and age check
       $this->php_session_id = $_COOKIE["PHPSESSID"];

       $stmt = "select id from user_session where ascii_session_id = '" . $this->php_session_id . "' AND ((now() - created) < ' " . $this->session_lifespan . " seconds') AND user_agent='" . $strUserAgent . "' AND ((now() - last_impression) <= '".$this->session_timeout." seconds' OR last_impression IS NULL)";

       $result = $this->objDB->select($stmt);
       if ($result->numRows() == 0) {
         # Set failed flag
         $failed = 1;
         # Delete from database - we do garbage cleanup at the same time
         $result = $this->objDB->delete('user_session', "(ascii_session_id = '". $this->php_session_id . "') OR ((now() - created) > " . $this->session_lifespan . ")");
         # Clean up stray session variables
         $session_ids_query = $this->objDB->select("SELECT id FROM user_session");
         $session_ids = $session_ids_query->getCol;

         if (count($session_ids) > 0) $result = $this->objDB->delete('session_variable', array("session_id NOT IN (" . implode(",", $session_ids) . ")"));
         # 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) {
        $result = $this->objDB->update('user_session', array('last_impression' => date("YmdHis")), "id = " . $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("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);
      $result = $this->objDB->select("select id FROM user WHERE username = '$strUsername' AND md5_pw = '$strMD5Password'");

      if ($result->numRows() > 0) {
        $row = $result->fetchRow();
        $this->user_id = $row["id"];
        $this->logged_in = true;
        $result = $this->objDB->update('user_session', array('logged_in' => 1, 'user_id' => $this->user_id), "id = '" . $this->native_session_id . "'");
        return(true);
      } else {
        return(false);
      };
    }

    public function LogOut() {
      if ($this->logged_in == true) {
        $result = $this->objDB->update('user_session', array('logged_in' => 0, 'user_id' => 0), "id = '" . $this->native_session_id . "'");
        $this->logged_in = false;
        $this->user_id = 0;
        return(true);
      } else {
        return(false);
      };
    }

    public function __get($nm) {
      $result = $this->objDB->select("SELECT variable_value FROM session_variable WHERE session_id = " . $this->native_session_id . " AND variable_name = '" . $nm . "'");
      if ($result->numRows() > 0) {
        $row = $result->fetchRow();
        return(unserialize($row["variable_value"]));
      } else {
        return(false);
      };
    }


    public function __set($nm, $val) {
      $strSer = serialize($val);
      //if the variable has already been set, overwrite it
      $count = $this->objDB->getOne("SELECT COUNT(1) FROM session_variable WHERE variable_name = '" . $nm . "'");
      if ($count > 0){
        //update
        $result = $this->objDB->update('session_variable', array('variable_value' => $strSer), "variable_name = '" . $nm . "'");
      }
      else {
        //insert
        $result = $this->objDB->insert('session_variable', array('session_id' => $this->native_session_id, 'variable_name' => $nm, 'variable_value' => $strSer));
      }
    }

    private function _session_open_method($save_path, $session_name) {
      # Do nothing
      return(true);
    }

    public function _session_close_method() {
      return(true);
    }

    private function _session_read_method($id) {
      # We use this to determine whether or not our session actually exists.
      $strUserAgent = $GLOBALS["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.
      $result = $this->objDB->select("select id, logged_in, user_id from user_session where ascii_session_id LIKE '" . $id . "'");

      if ($result->numRows() > 0) {
       $row = $result->fetchRow();
       $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
        $result = $this->objDB->insert('user_session', array('ascii_session_id' => $id, 'logged_in' => 0, 'user_id' => 0, 'created' => date("YmdHis"), 'user_agent' => $strUserAgent));
        # Now get the true ID
        $result = $this->objDB->select("select id from user_session where ascii_session_id = '" . $id . "'");
        $row = $result->fetchRow();
        $this->native_session_id = $row["id"];
      };
      # Just return empty string
      return("");
    }

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

    private function _session_destroy_method($id) {
      $result = pg_query("DELETE FROM \"user_session\" WHERE ascii_session_id = '$id'");
      return($result);
    }

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


  }
?>

Sorry for the long post, hope this helps!

Ed

  #5 (permalink)  
Old July 7th, 2005, 06:03 PM
Registered User
 
Join Date: Jun 2005
Location: , , .
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

A quick correction on my previous post, I am using a tinyint to store logged_in in the user_session table (in MySQL 4.1.0 and above BOOL is a synonym for TINYINT - http://dev.mysql.com/doc/mysql/en/nu...-overview.html). To make this work change:

if ($row["logged_in"]=="t")

to:

if ($row["logged_in"]==1)

in the _session_read_method function. Otherwise the function does not correctly evaluate whether the user is logged in or not

  #6 (permalink)  
Old July 30th, 2005, 10:54 AM
ncc ncc is offline
Registered User
 
Join Date: Jul 2005
Location: , , .
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Default

After much research on the session topic and the object provided by the book, I realize that several things are pretty unusable. They are as follows:

a) You will have to change several private functions as indicated by the book to public functions. This leads to the programmers into a much confused state.

b) Because the usersession class uses the session_set_save_handler function, only private variable such as native_session_id and session_id will be remembered throughout the entire session. Hence, it can be remembered in another page even a new Usersession instance is created there. This is because any variables assignment used in the session_read_method function (one of the the special functions utilised by session_set_save_handler) will be remembered throughout the session.

Other private variables such as logged_in will never be able to shared in other page when you declared the usersession object as a new instance. In the other word, any other functions not utilized by session_set_save_handler are considered a "stand-a-lone" function. When you declare a new instance of usersession class, you will realize that the values are only valid by each instance, not shared, which is not what you wish to have since usersession is supposed to be shared across other pages.

Research from php.net forum has shown that user authenizatication should not be used in the session_set_save_handler function, as explained by Robert Chapin. And my research shows likewise as variables cannot be transferred between pages.

My advise is to remove:
- function Login($strUserName, $strPlainPassword),
- function LogOut(),

Create another user class for login and authentication purposes.

For user "mlange"'s kind of problem, if you wish to share data between pages, consider the overloading method. As "mlange" has said that:

<QUOTE>
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...
</QUOTE>

Consider this:

page1.php

$usersession = new usersession();
$login = new login($username, $userpwd);

if ($login->loginstatus == true)
{
   $usersession->LOGINSTATUS = TRUE;
   // Same statement: $_SESSION["LOGINSTATUS"] = TRUE;
   // But we used the OOP method instead with having
   // storing the session in our database, instead to a file

}
else
{ $usersession->LOGINSTATUS = FALSE;
    // Same statement: $_SESSION["LOGINSTATUS"] = TRUE;
    // But we used the OOP method instead with having
    // storing the session in our database, instead to a file
}

// Put some methods to go to page2.php
   :
   :
   :


page2.php
$usersession = new usersession();

//Check if the user has login:
// Same as: if ($_SESSION["LOGINSTATUS"] == TRUE)
if ($usersession->LOGINSTATUS == TRUE)
{
   echo "User has login";
}
ELSE
{
   echo "User failed to login";
}

c) I think the garbage collection method needs to improve on it on the construct. (Correct me if I am wrong ...) I think there is no requirement for us to place this statement:

if(isset($_COOKIE["PHPSESSID"]))

Also, I think the session_gc_method can be the function that stores all the necessary garbage collection.

Likewise, I think garbage collection should be imposed on Impress method first before you perform any query on the database to update the last_impression field. This is because the user may not have been active for a while and there is no way currently accessing the session class. This will enhance security.

Just my two cents worth of thoughts.

Ng Cher Choon

  #7 (permalink)  
Old September 6th, 2005, 07:03 AM
Registered User
 
Join Date: Sep 2005
Location: , , .
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I guess the general consensus on here is the UserSession class is basically useless for
production purposes and that one is better off taking the idea and rewriting the whole
concept from scratch? That seems easier than all the confusion surrounding the code
they forced us to hack away at.

  #8 (permalink)  
Old March 7th, 2006, 01:39 PM
Registered User
 
Join Date: Mar 2006
Location: , New York, USA.
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
quote:Originally posted by amnesiacx
 I guess the general consensus on here is the UserSession class is basically useless for
production purposes and that one is better off taking the idea and rewriting the whole
concept from scratch? That seems easier than all the confusion surrounding the code
they forced us to hack away at.

That's what I am doing... although I planned on doing that anyways since I figure it's the best way to know what exactly is going on. However, there was still some things that really threw me(which is why I came here). Such as the fact that the close and write methods needed to be public. Obviously I quickly made them public, but that left me thinking that I did something wrong.


  #9 (permalink)  
Old January 4th, 2007, 11:11 AM
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);
    }
}
?>
  #10 (permalink)  
Old February 27th, 2007, 10:27 AM
Registered User
 
Join Date: Feb 2007
Location: Donetsk, , Ukraine.
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via ICQ to hammet
Default

Can anybody helps me...?
I rewrite this class for MySQL. But it didn't works.

Fatal error: Call to private method Auth::_session_write_method() from context '' in Unknown on line 0

Fatal error: Call to private method Auth::_session_close_method() from context '' in Unknown on line 0


class code here:
Code:
<?php
  error_reporting(E_ALL ^ E_NOTICE);

  include "config.php";

  class Auth {

    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

    private $dbhost;
    private $dblogin;
    private $dbpass;
    private $dbname;

    public function __construct() {

      # Connect to database
      $this->dbhost  = DB_HOST; 
      $this->dblogin = DB_USER;
      $this->dbpass  = DB_PASS;
      $this->dbname  = DB_NAME;
      $link = @mysql_connect($this->dbhost, $this->dblogin, $this->dbpass);
      @mysql_select_db($this->dbname, $link);

      # 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 = $GLOBALS["HTTP_USER_AGENT"];
      if ($_COOKIE["PHPSESSID"]) {
       # Security and age check
       $this->php_session_id = $_COOKIE["PHPSESSID"];
       $stmt = "select id from `kc_user_session` where ascii_session_id = '" . $this->php_session_id . "' AND ((now() - created) < ' " . $this->session_lifespan . " seconds') AND user_agent='" . $strUserAgent . "' AND ((now() - last_impression) <= '".$this->session_timeout." seconds' OR last_impression IS NULL)";
       $result = mysql_query($stmt);
       if (mysql_num_rows($result)==0) {
         # Set failed flag
          $failed = 1;
         # Delete from database - we do garbage cleanup at the same time
         $result = mysql_query("DELETE FROM `kc_user_session` WHERE (ascii_session_id = '". $this->php_session_id . "') OR (now() - created) > $maxlifetime)");
         # Clean up stray session variables
         $result = mysql_query("DELETE FROM `kc_session_variable` WHERE session_id NOT IN (SELECT id FROM `user_session`)");
         # 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) {
        $result = mysql_query("UPDATE `kc_user_session` SET last_impression = now() WHERE id = " . $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("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);
      $stmt = "select id FROM `kc_users` WHERE login = '$strUsername' AND password = '$strMD5Password'";
      $result = mysql_query($stmt);
      if (mysql_num_rows($result)>0) {
        $row = mysql_fetch_array($result);
        $this->user_id = $row["id"];
        $this->logged_in = true;
        $result = mysql_query("UPDATE `kc_user_session` SET logged_in = true, user_id = " . $this->user_id . " WHERE id = " . $this->native_session_id);
        return true;
      } 
      else {
        return false;
      }
    }  

    public function LogOut() {
      if ($this->logged_in == true) {
        $result = mysql_query("UPDATE `kc_user_session` SET logged_in = false, user_id = 0 WHERE id = " . $this->native_session_id);
        $this->logged_in = false;
        $this->user_id = 0;
        return(true);
      } else {
        return(false);
      }
    }

    public function __get($nm) {
      $result = mysql_query("SELECT variable_value FROM `kc_session_variable` WHERE session_id = " . $this->native_session_id . " AND variable_name = '" . $nm . "'");
      if (mysql_num_rows($result)>0) {
        $row = mysql_fetch_array($result);
        return(unserialize($row["variable_value"]));
      } else {
        return(false);
      }
    }


    public function __set($nm, $val) {
      $strSer = serialize($val);
      $stmt = "INSERT INTO kc_session_variable(session_id, variable_name, variable_value) VALUES(" . $this->native_session_id . ", '$nm', '$strSer')";
      $result = mysql_query($stmt);
    }

    public function _session_open_method($save_path, $session_name) {
      # Do nothing
      return(true);
    }

    private function _session_close_method() {
      @mysql_close($this->link);
      return(true);
    }

    private function _session_read_method($id) {
      # We use this to determine whether or not our session actually exists.
      $strUserAgent = $GLOBALS["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.
      $result = mysql_query("select id, logged_in, user_id from `kc_user_session` where ascii_session_id = '$id'");
      if (mysql_num_rows($result)>0) {
       $row = mysql_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
        $result = mysql_query("INSERT INTO kc_user_session (ascii_session_id, logged_in, user_id, created, user_agent) VALUES ('$id','f',0,now(),'$strUserAgent')");
        # Now get the true ID
        $result = mysql_query("select id from `kc_user_session` where ascii_session_id = '$id'");
        $row = mysql_fetch_array($result);
        $this->native_session_id = $row["id"];
      };
      # Just return empty string
      return("");
    }

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

    private function _session_destroy_method($id) {
      $result = mysql_query("DELETE FROM `kc_user_session` WHERE ascii_session_id = '$id'");
      return($result);
    }

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


  }
?>
...Thanks!




Similar Threads
Thread Thread Starter Forum Replies Last Post
Chapter 15: usersession.phpm database conversion cashflowtips BOOK: Professional PHP 5 ISBN: 978-0-7645-7282-1 1 August 9th, 2007 04:00 AM
chapter 15 manal_sag BOOK: Beginning ASP 3.0 2 March 13th, 2006 04:48 PM
chapter 15 manal_sag BOOK: Beginning ASP 3.0 0 April 22nd, 2005 02:23 PM
Chapter 15 moggie BOOK: Beginning ASP 3.0 2 October 19th, 2004 01:30 PM
Chapter 15!! studentinpain BOOK: Beginning ASP 3.0 16 March 12th, 2004 10:26 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.