Session Help

I’m trying to learn about sessions from an OO point of view by viewing and using code from “Professional PHP5” (book I purchased), and I’m a bit lost on, what I believe, are some method overrides. I however cannot find documentation on these. Here’s the code causing Fatal Error’s:


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

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

Both produce the following Errors:

Fatal error: Call to private method UserSession::_session_write_method() from context ‘’ in Unknown on line 0

Fatal error: Call to private method UserSession::_session_close_method() from context ‘’ in Unknown on line 0

I’m a bit lost on how to track down what the problem is. The other overrides work and the other functions instantiated on the object are in working order. The test script I’m using can be viewed at http://www.loserwars.com/session/sessiontest.php

Any ideas, pointers or need for more code requests are appreciated. the "from context “” is what is baffling me. Thanks.

Edit: Some code that might help is as follows:

//Session 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')
);

GottaGoMedia,

Did you find solution for this.

If then post the solution here, we would like to know.

Nope…still working on it. Day 3.

Can you post the whole code for the session class?

<?php
require_once('../main/config.php');
require_once('../database/class.database.php');

class UserSession {
	private $php_session_id;
	private $native_session_id;
	private $db;
	private $logged_in;
	private $user_id;
	private $session_timeout = 600;
	private $session_lifespan = 3600;


	public function __construct() {

		//Connection to DB
		try {
			$objDB = Database::instance();
			print "<p>Database Object Created</p>";
		} catch (Exception $e) {
			echo $e->getMessage();
			exit(2);
		}

		//Session 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')
		);
		print "<p>Session Handler Set</p>";

		//Check the cookie passed - if one is - if it looks wrong we will scrub it right away
		$strUserAgent = $GLOBALS["HTTP_USER_AGENT"];
		if($_COOKIE["PHPSESSID"]) {
			print "<p>Cookie EXISTS Proceed...</p>";
			//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)
				";
			print "<p>Before user_session query: $stmt</p>";
			$result = mysql_query($stmt) or die("mysql error in session_set_save_handler " . mysql_error() . " in query $query");
			if(mysql_num_rows($result)==0) {
				//Set failed flag
				$failed - 1;
				//Delete from database - we do garbage cleanup at the same time
				$stmt =	"
						DELETE FROM session_variable 
						WHERE session_id 
						NOT IN (
						SELECT id FROM user_session)
					";
				$result = mysql_query($stmt,$this->conn) or die("mysql error in session_set_save_handler " . mysql_error() . " in query $query");
				//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 up Session Handler
		//session_set_save_handler(
		//Call the session_start method to get things started
		print "<p>Before Session_start()</p>";
		session_start();
		print "<p>Cookie didn't exist and Session started</p>";
	}

	public function Impress() {
		if($this->native_session_id) {
			$stmt = "
					UPDATE user_session 
					SET last_impression = now() 
					WHERE id = '" . $this->native_session_id . "'
				";
			$result = mysql_query($stmt,$this->conn) or die("mysql error in Impress " . mysql_error() . " in query $query");
		};
	}

	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($strEmail, $strPlainPassword) {
		$strMD5Password = md5($strPlainPassword);
		$stmt = "
				SELECT id 
				FROM users 
				WHERE email = '$strEmail' 
				AND password = '$strMD5Password'
			";
		$result = mysql_query($stmt,$this->conn) or die("mysql error in Login " . mysql_error() . " in query $query");;
		if(mysql_num_rows($result)>0) {
			$row = mysql_fetch_array($result);
			$this->user_id = $row["id"];
			$this->logged_in = true;
			$stmt = "
					UPDATE user_session 
					SET logged_in = true
						, user_id = " . $this->user_id . " 
					WHERE id = '". $this->native_session_id . "'
				";
			$result = mysql_query($stmt,$this->conn) or die("mysql error in Login " . mysql_error() . " in query $query");
			return(true);
		} else {
			return(false);
		};
	}

	public function LogOut() {
		if($this->logged_in == true) {
			$stmt = "
					UPDATE user_session 
					SET logged_in = false
						, user_id = 0 
					WHERE id = '" . $this->native_session_id . "'
				";
			$result = mysql_query($stmt,$this->conn)  or die("mysql error in Logout " . mysql_error() . " in query $query");
			$this->logged_in = false;
			$this->user_id = 0;
			return(true);
		} else {
			return(false);
		};
	}

	public function __get($nm) {
		$stmt = "
				SELECT variable_value 
				FROM session_variable 
				WHERE session_id = " . $this->native_session_id . " 
				AND variable_name = '" . $nm . "'
			";
		echo "$stmt"; die();
		$result = mysql_query($stmt)  or die("mysql error in __get " . mysql_error() . " in query $query");
		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 session_variable(
					session_id
					, variable_name
					, variable_value) 
				VALUES(" . $this->native_session_id . ", '$nm', '$strSer')
			";
		$result = mysql_query($stmt,$this->conn)  or die("mysql error in __set " . mysql_error() . " in query $query");
	}

	private function _session_open_method($save_path, $session_name) {
		//Do Nothing
		return(true);
	}

	private function _session_close_method() {
		echo "$this->conn"; die();
		mysql_close($this->conn);
		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.
		$stmt = "
  				SELECT
      					id
    					, logged_in
    					, user_id
  				FROM user_session
  				WHERE ascii_session_id = '$id'
			";
		$result = mysql_query($stmt, $this->conn) or die("mysql error _session_read_method 1 " . mysql_error() . " in query $stmt");
		if(mysql_num_rows($result)>0) {
			$row = mysql_fetch_array($result);
			$this->native_session_id = $row["id"];
			if($row["logged_in"] == "1") {
				$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 to the database
			$stmt = "
					INSERT INTO user_session(
						ascii_session_id
						,logged_in
						,user_id
						,created
						,user_agent) 
					VALUE ('$id','f',0,now(),'$strUserAgent')
				";
			$result = mysql_query($stmt,$this->conn)  or die("mysql error in _session_read_method 2 " . mysql_error() . " in query $query");
			//Now get the true ID
			$stmt = "
					SELECT id 
					FROM user_session 
					WHERE ascii_session_id = '$id'
				";
			$result = mysql_query($stmt,$this->conn)  or die("mysql error in _session_read_method 3 " . mysql_error() . " in query $query");
			$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) {
		$stmt = "
				DELETE FROM user_session 
				WHERE ascii_session_id = 'id'
			";
		$result = mysql_query($stmt,$this->conn)  or die("mysql error in _session_destroy_method " . mysql_error() . " in query $query");
		return($result);
	}

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


?>

sessiontest.php (so far)

<?php

require_once("usersession.phpm");
require_once("../debug/class.debugger.php");
print "<p>Before UserSession Creation</p>";
$objSession = new UserSession();
print "<p>UserSession created</p>";
$objSession->Impress();
print "<p>Session Impression Complete</p>";
Debugger::debug($objSession,'objSession');

?>
UserSession Test Page
<hr>
<b>Current Session ID: </b> <?=$objSession->GetSessionIdentifier();?><br>
<b>Logged in? </b> <?=(($objSession->IsLoggedIn() == true) ? "Yes" : "No")?><br>
Attempting to log in ...
<?php $objSession->Login("ed@example.com","12345"); ?>
<br><br><?php Debugger::debug($objSession,'objSession');?>
<b>Logged in? </b> <?=(($objSession->IsLoggedIn() == true) ? "Yes" : "No")?><br>
<b>User ID of logged in user: </b> <?=$objSession->GetUserID();?><br>
<br><br>
Now Logging Out ...
<?php $objSession->Logout();?>
<br><br>
<b>Logged in? </b><?=(($objSession->IsLoggedIn() == true) ? "Yes" : "No")?><br><br><br>
<?php
?>

Current Output from various echo’s and prints throughout:

Before UserSession Creation

Database Object Created

Session Handler Set

Before Session_start()
SELECT variable_value FROM session_variable WHERE session_id = AND variable_name = 'conn'

As you can see it’s dieing somewhere in the handler functions. I’m trying to wade through this documentation as I don’t understand what’s going on in session_set_save_handler. The SQL statement in the output is in _get and for whatever reason session_id isn’t being set and I have no clue where ‘conn’ came from. I’m working on it currently and any help is much appreciated.

did you intend to put the m on the end of usersession.phpm? You sure you’re modifying the right file? (IE: Is there a usersession.php and a usersession.phpm?)


                $failed - 1;

Missed an = there, methinks…

From what you’re showing, this is running correctly up until the call of session_start, given that if($_COOKIE[“PHPSESSID”]) {
evaluates to false. (Really this should be an isset, no?)

I’ll start with code :slight_smile: :

require_once('../database/class.database.php');

class UserSession {
	private $php_session_id;
	private $native_session_id;
	private $db;
	private $conn;
	private $logged_in;
	private $user_id;
	private $session_timeout = 600;
	private $session_lifespan = 3600;


	public function __construct() {		//Connection to DB
		try {
			$this->conn = Database::instance();
			if(DB::isError($this->conn)) {
				throw new Exception($this->conn->getMessage(), $this->conn->getCode());
			}
		} catch (Exception $e) {
			echo $e->getMessage();
			exit(2);
		}

		//Session 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 will scrub it right away
		$strUserAgent = $GLOBALS["HTTP_USER_AGENT"];
		if(isset($_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 = mysql_query($stmt) or die("mysql error in session_set_save_handler " . mysql_error() . " in query $query");
			if(mysql_num_rows($result)==0) {
				//Set failed flag
				$failed = 1;
				//Delete from database - we do garbage cleanup at the same time
				$stmt =	"
						DELETE FROM session_variable 
						WHERE session_id 
						NOT IN (
						SELECT id FROM user_session)
					";
				$result = mysql_query($stmt) or die("mysql error in session_set_save_handler " . mysql_error() . " in query $query");
				//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 up Session Handler here ??????????????

		//Call the session_start method to get things started
		session_start();
	}

	public function Impress() {
		if($this->native_session_id) {
			$stmt = "
					UPDATE user_session 
					SET last_impression = now() 
					WHERE id = '" . $this->native_session_id . "'
				";
			$result = mysql_query($stmt) or die("mysql error in Impress " . mysql_error() . " in query $query");
		};
	}

	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($strEmail, $strPlainPassword) {
		$strMD5Password = md5($strPlainPassword);
		$stmt = "
				SELECT id 
				FROM users 
				WHERE email = '$strEmail' 
				AND password = '$strMD5Password'
			";
		$result = mysql_query($stmt) or die("mysql error in Login " . mysql_error() . " in query $query");;
		if(mysql_num_rows($result)>0) {
			$row = mysql_fetch_array($result);
			$this->user_id = $row["id"];
			$this->logged_in = true;
			$stmt = "
					UPDATE user_session 
					SET logged_in = true
						, user_id = " . $this->user_id . " 
					WHERE id = '". $this->native_session_id . "'
				";
			$result = mysql_query($stmt) or die("mysql error in Login " . mysql_error() . " in query $query");
			return(true);
		} else {
			return(false);
		};
	}

	public function LogOut() {
		if($this->logged_in == true) {
			$stmt = "
					UPDATE user_session 
					SET logged_in = false
						, user_id = 0 
					WHERE id = '" . $this->native_session_id . "'
				";
			$result = mysql_query($stmt)  or die("mysql error in Logout " . mysql_error() . " in query $query");
			$this->logged_in = false;
			$this->user_id = 0;
			return(true);
		} else {
			return(false);
		};
	}

	public function __get($nm) {
		$stmt = "
				SELECT variable_value 
				FROM session_variable 
				WHERE session_id = " . $this->native_session_id . " 
				AND variable_name = '" . $nm . "'
			";
		echo "$stmt"; die();
		$result = mysql_query($stmt)  or die("mysql error in __get " . mysql_error() . " in query $query");
		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 session_variable(
					session_id
					, variable_name
					, variable_value) 
				VALUES(" . $this->native_session_id . ", '$nm', '$strSer')
			";
		echo "stmt in __set(): $stmt"; die();
		$result = mysql_query($stmt,$this->conn)  or die("mysql error in __set " . mysql_error() . " in query $query");
	}

	private function _session_open_method($save_path, $session_name) {
		//Do Nothing
		return(true);
	}

	private function _session_close_method() {
		$this->conn->disconnect();
		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.
		$stmt = "
  				SELECT
      					id
    					, logged_in
    					, user_id
  				FROM user_session
  				WHERE ascii_session_id = '$id'
			";
		$result = mysql_query($stmt) or die("mysql error _session_read_method 1 " . mysql_error() . " in query $stmt");
		if(mysql_num_rows($result)>0) {
			$row = mysql_fetch_array($result);
			$this->native_session_id = $row["id"];
			if($row["logged_in"] == "1") {
				$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 to the database
			$stmt = "
					INSERT INTO user_session(
						ascii_session_id
						,logged_in
						,user_id
						,created
						,user_agent) 
					VALUE ('$id','f',0,now(),'$strUserAgent')
				";
			$result = mysql_query($stmt)  or die("mysql error in _session_read_method 2 " . mysql_error() . " in query $query");
			//Now get the true ID
			$stmt = "
					SELECT id 
					FROM user_session 
					WHERE ascii_session_id = '$id'
				";
			$result = mysql_query($stmt)  or die("mysql error in _session_read_method 3 " . mysql_error() . " in query $query");
			$row = mysql_fetch_array($result);
			$this->native_session_id = $row["id"];
		};
		return("");
	}

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

	private function _session_destroy_method($id) {
		$stmt = "
				DELETE FROM user_session 
				WHERE ascii_session_id = 'id'
			";
		$result = mysql_query($stmt)  or die("mysql error in _session_destroy_method " . mysql_error() . " in query $query");
		return($result);
	}

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

That’s my revised copy. Changed some things around. Mostly query’s.

sessiontest.php:

require_once("usersession.phpm");
require_once("../debug/class.debugger.php");

$objSession = new UserSession();
$objSession->Impress();

Debugger::debug($objSession,'objSession');

?>
UserSession Test Page
<hr>
<b>Current Session ID: </b> <?=$objSession->GetSessionIdentifier();?><br>
<b>Logged in? </b> <?=(($objSession->IsLoggedIn() == true) ? "Yes" : "No")?><br>
Attempting to log in ...
<?php $objSession->Login("ed@example.com","12345"); ?>
<br><br><?php Debugger::debug($objSession,'objSession');?>
<b>Logged in? </b> <?=(($objSession->IsLoggedIn() == true) ? "Yes" : "No")?><br>
<b>User ID of logged in user: </b> <?=$objSession->GetUserID();?><br>
<br><br>
Now Logging Out ...
<?php $objSession->LogOut();?><br>
<b>Current Session ID: </b> <?=$objSession->GetSessionIdentifier();?><br>
<br><br>
<b>Logged in? </b><?=(($objSession->IsLoggedIn() == true) ? "Yes" : "No")?><br><br><br>
<?php
?>

Sessions are being created and stored correctly in the database. I’m that far along. However, they’re not being deleted. I have read up a bit on session_set_save_handler and there’s some things I’m not understanding. It’s stated that in php5.0.5 that write and close are called after the deconstructor. How can I act on the object? How/when do I know when it’s been destroyed?

		session_set_cookie_params($this->session_lifespan);
		//Call up Session Handler here ??????????????

		//Call the session_start method to get things started
		session_start();

Since I have overridden the methods do I need to call session_set_save_hander like the documentation shows?

session_set_save_handler("open", "close", "read", "write", "destroy", "gc");

Any insight is so very much appreciated. Doing my best to learn :).

By “sessions not being deleted” are you refering to seesions not being deleted when a user logs out or “stale” sessions not being deleted? Looking at the code

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

you’re not deleting “stale” sessions

Is there any reason or instance where I want to keep a session in the Database after a User logs out or timesout?

Okay, I’m doing my best to understand this. That being said, I have questions :).

$strUserAgent = $GLOBALS["HTTP_USER_AGENT"];

$srUserAgent is empty here. Why doesn’t it populate?

In _session_read_method:

	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;
		print "<p>User Agent: $strUserAgent - php_session_id: " . $this->php_session_id . "</p>";
		//Set failed flag to 1 for now
		$failed = 1;
		//See if this exists in the database or not.
		$stmt = "
  				SELECT
      					id
    					, logged_in
    					, user_id
  				FROM user_session
  				WHERE ascii_session_id = '$id'
			";
		$result = mysql_query($stmt) or die("mysql error _session_read_method 1 " . mysql_error() . " in query $stmt");
		print "<p>num_rows: " . mysql_num_rows($result) . "</p>";
		if(mysql_num_rows($result)>0) {
			$row = mysql_fetch_array($result);
			$this->native_session_id = $row["id"];
			print "<p>native_session_id " . $this->native_session_id . "</p>";
			if($row["logged_in"] == "1") {
				$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 to the database
			$stmt = "
					INSERT INTO user_session(
						ascii_session_id
						,logged_in
						,user_id
						,created
						,user_agent) 
					VALUE ('$id','f',0,now(),'$strUserAgent')
				";
			$result = mysql_query($stmt)  or die("mysql error in _session_read_method 2 " . mysql_error() . " in query $query");
			//Now get the true ID
			$stmt = "
					SELECT id 
					FROM user_session 
					WHERE ascii_session_id = '$id'
				";
			$result = mysql_query($stmt)  or die("mysql error in _session_read_method 3 " . mysql_error() . " in query $query");
			$row = mysql_fetch_array($result);
			$this->native_session_id = $row["id"];
		};
		return("");
	}

Should I move the “else” into _session_write_method? It seems like I wouldn’t want this here.

	private function _session_write_method($id, $sess_data) {
		print "<p>ID: $id - Sess_data: $sess_data</p>"; die();
		return(true);
	}

	private function _session_destroy_method($id) {
		$stmt = "
				DELETE FROM user_session 
				WHERE ascii_session_id = 'id'
			";
		$result = mysql_query($stmt)  or die("mysql error in _session_destroy_method " . mysql_error() . " in query $query");
		return($result);
	}

These two methods are never even called. So, admittedly dumbfounded, why?
Also, should these be public functions? Every reference I can find to using sessions on an object to store in a database declare the functions as public. Why? That doesn’t make sense to me.

Again any help is thanked thoroughly.

Okay, rewrote this one as well. Simplified it a bit. Now I’m having a problem with mysql_num_rows();

Code:

&lt;?php
require_once('class.database.php');
require_once('DB.php');
require_once('config.php');
/*
NEED:	require_once('class.session.php');
	$sess = new Session();
	session_start();
	At the beginning of files.	
NEED: session_write_close(); at the end of each file to retain sessions!
*/
class Session {
	private $session_timeout = 600;
	private $session_lifespan = 3600;
	private $conn;

	public function __construct() {
		global $cfg;
		$this-&gt;session_lifespan = get_cfg_var("session.gc_maxlifetime");

		if($dsn == null) {
			$dsn = $cfg['db']['dsn'];
		} else {
			print "&lt;p&gt;Problem connecting to database&lt;/p&gt;";
		}
		$this-&gt;conn =& DB::connect($dsn);
		if(DB::isError($this-&gt;conn)) {
			print "&lt;p&gt;Thrown Here&lt;/p&gt;";
			throw new Exception($this-&gt;conn-&gt;getMessage(), $this-&gt;conn-&gt;getCode());
		}
		$this-&gt;conn-&gt;setFetchMode(DB_FETCHMODE_ASSOC);	
		session_set_save_handler(
			array(&$this, 'open'),
			array(&$this, 'close'),
			array(&$this, 'read'),
			array(&$this, 'write'),
			array(&$this, 'destroy'),
			array(&$this, 'gc')
		);
	}

	function open($save_path, $session_name) {
		global $sess_save_path;

		$sess_save_path = $save_path;
		return true;
	}

	function close() {
		try {
			$this-&gt;conn-&gt;disconnect();
		} catch (Exception $e) {
			echo $e-&gt;getMessage();
			exit(2);
		}
		return true;
	}

	function read($id) {
		$data = '';
		$time = time();
		$newid = mysql_real_escape_string($id);
		$sql = "SELECT 'session_data' FROM session WHERE session_id = '$newid' AND expire &gt; " .time();
		$result = $this-&gt;conn-&gt;query($sql) or die(mysql_error());
		if(DB::isError($result)) {
			throw new Exception($result-&gt;getMessage(), $result-&gt;getCode());
		}
		$a = mysql_num_rows($result) or die(mysql_error());
		if($a &gt; 0) {
			$row = mysql_fetch_assoc($result);
			$data = $row['session_data'];
		}
		return $data;
	}

	function write($id, $data) {
		$time = time() + $this-&gt;session_lifespan;
		$newid = mysql_real_escape_string($id);
		$newdata = mysql_real_escape_string($data);
		$sql = "REPLACE session (session_id,session_data,expire) VALUES('$newid','$newdata',$time)";
		$result = $this-&gt;conn-&gt;query($sql);
		if(DB::isError($result)) {
			throw new Exception($result-&gt;getMessage(), $result-&gt;getCode());
		}
		return true;
	}

	function destroy($id) {
		$newid = mysql_real_escape_string($id);
		$sql = "DELETE FROM 'session' WHERE 'session_id' = '$newid'";
		$result = $this-&gt;conn-&gt;query($sql);
		if(DB::isError($result)) {
			throw new Exception($result-&gt;getMessage(), $result-&gt;getCode());
		}
		return true;
	}

	function gc() {
		$sql = "DELETE FROM `session` WHERE 'expire' &lt; UNIX_TIMESTAMP();";
		$result = $this-&gt;conn-&gt;query($sql);
		if(DB::isError($result)) {
			throw new Exception($result-&gt;getMessage(), $result-&gt;getCode());
		}
		return true;
	}

	public function GetSessionIdentifier() {
		return($this-&gt;session_id);
	}
}
?&gt;

Warning:

Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource

Lines in warning:

$a = mysql_num_rows($result) or die(mysql_error());

I’ve tried everything I can think of to eliminate the error. I’ve checked and rechecked the connection. I’ve serialized $result to see what’s going on there. Nothing out of the ordinary that I can tell. Any help is much appreciated.

Okay, rewrite #4:

class Session {
	private $session_timeout = 600;
	private $session_lifespan = 3600;
	private $conn;

	function __construct() {
		global $cfg;
		$this-&gt;session_lifespan = get_cfg_var("session.gc_maxlifetime");

		$username = $cfg['db']['user'];
		$pass = $cfg['db']['pass'];
		$host = $cfg['db']['host'];
		$db = $cfg['db']['database'];
		$this-&gt;conn = mysql_connect($host,$username,$pass) or die(mysql_error());
		mysql_select_db($db,$this-&gt;conn) or die(mysql_error());



		session_set_save_handler(
			array(&$this, 'open'),
			array(&$this, 'close'),
			array(&$this, 'read'),
			array(&$this, 'write'),
			array(&$this, 'destroy'),
			array(&$this, 'gc')
		);
		session_start();
		
	}

	function open($save_path, $session_name) {
		return true;
	}

	function close() {
		if(!empty($this-&gt;data)) {
			$gc = $this-&gt;gc(ini_get('session.gc_maxlifetime'));
			mysql_close();
			return $gc;
		} else {
			return False;
		}
	}

	function read($id) {
		$data = '';
		$time = time();
		$newid = mysql_real_escape_string($id);

		$sql = "SELECT session_data FROM session WHERE session_id = '$newid'";
		$result = mysql_query($sql) or die(mysql_error());
		echo "$newid";
		if(isset($result[0]['session_data'])) {
			$this-&gt;data = $result[0];
			$this-&gt;data['session_data'] = ' ';
			return $result[0]['session_data'];
		} else {
			return '';
		}
	}

	function write($id, $data) {
		$time = time() + $this-&gt;session_lifespan;
		$newid = mysql_real_escape_string($id);
		$newdata = mysql_real_escape_string($data);
		echo "$newid";
		echo "$newdata";

		if(!empty($this-&gt;data)) {	
			if($this-&gt;data['session_id'] != $newid) {
				$this-&gt;data = '';
			}
			print "Data isn't empty: $this-&gt;data";
		}
		die();

		if(empty($this-&gt;data)) {
			$session_id = $newid;
			$created = getTimeStamp();
			$last = getTimeStamp();
			$session_data = $newdata;
			$sql = "INSERT INTO session (session_id,session_data,last,created,expire) VALUES('$session_id','$session_data',$last,$created,$time)";
			$result = mysql_query($sql) or die(mysql_error());
		} else {
			if(isset($_SESSION['user_id'])) {
				$user_id = $_SESSION['user_id'];
			}
			$last = getTimeStamp();
			$session_data = $newdata;
			$sql = 'UPDATE session SET last = "$last", session_data = "$session_data" WHERE session_id = "$newid"';
			$result = mysql_query($sql) or die(mysql_error());
		}
		return true;
	}

	function destroy($id) {
		$newid = mysql_real_escape_string($id);
		echo "$newid";
		
		$sql = "DELETE FROM 'session' WHERE 'session_id' = '$newid'";
		$result = mysql_query($sql) or die(mysql_error());
		return true;
	}

	function gc($max_lifetime) {
		$now = date('Y-m-d H:i:s');
		$sDate = strtotime("$now -$max_lifetime seconds");
		$date = date('Y-m-d H:i:s',$sDate);
		$sql = "DELETE FROM `session` WHERE last &lt; '$date'";
		$result = mysql_query($sql) or die(mysql_error());
		return true;
	}

	function __destruct() {
		@session_write_close();
	}
}
?&gt;

It’s never getting to the write function, so, nothing is ever written or updated in the database. Why? No Error’s, No warnings. I’m lost on why the object is allowed to instantiate without going through write…

Also, I’ve placed the session_set_save_handler and the session_start calls in the constructor. Is this a good practice or do I need to be calling it before every page is written? Thanks guys

Sorry posted that before I removed the die() in the write. My questions and wondering about write() still remain. Again, help is appreciated.

write function with print statements:

	function write($id, $data) {
		$this->data = $data;
		$time = time() + $this->session_lifespan;
		$newid = mysql_real_escape_string($id);
		$newdata = mysql_real_escape_string($data);
		print "<p>ID = $newid</p>";
		print "<p>Data: $data : $newdata</p>";

		if(!empty($this->data)) {	
			if($this->data['session_id'] != $newid) {
				$this->data = '';
				print "<p>Here</p>";
			}
			print "<p>Data isn't empty: $this->data</p>";
		}

		if(empty($this->data)) {
			$session_id = $newid;
			$created = getTimeStamp();
			$last = getTimeStamp();
			$session_data = $newdata;
			$sql = "INSERT INTO session (session_id,session_data,last,created,expire) VALUES('$session_id','$session_data',$last,$created,$time)";
			print "<p>Data is empty so we Inserted!</p>";
			$result = mysql_query($sql) or die(mysql_error());
			if(!$result) { print "<p>Insert result empty or null</p>"; }
		} else {
			if(isset($_SESSION['user_id'])) {
				$user_id = $_SESSION['user_id'];
			}
			$last = getTimeStamp();
			$session_data = $newdata;
			$sql = 'UPDATE session SET last = "$last", session_data = "$session_data" WHERE session_id = "$newid"';
			print "<p>Data wasnt empty so we updated.</p>";
			$result = mysql_query($sql) or die(mysql_error());
			if(!$result) { print "<p>Update result empty or null</p>"; }
		}
		return true;
	}

Driver:

<?php
require_once('class.session.php');
$session = new Session() or die("Error creating Session object");
echo "<p>Session Started</p>";
?>

Browser Output:

Session Started

ID = c6f9aqkhau2f0itn6sfl7ud1l6

Data: :

Why is it just dieing?

There are a lot of information about php sessions can be useful