Location: PHPKode > scripts > Jack's Session class > jacks-session-class/session.class.php
<?php
/**
 * @file	:	sesssion.class.php
 * @desc	:	sessions handling class
 * @lmod	:	13.09.2006
 */

class session
{
	// session idle
	var $max_idle;
	var $no_expire;
	
	// session values
	var $sessid;
	var $sesshost;
	
	var $variables;
	var $codelength = 20;
	
	// handlers
	var $dbh;
	
	// system messages
	var $messages = array();
	
	function session($host=null)
	{
		// get database link
		global $s;
		$this->dbh = & $s;
		
		 // set max idle time
         global $_MAX_IDLE;
         $this->max_idle = $_MAX_IDLE;
         
         // set no expire (actually it expires after a really long time)
         $this->no_expire = (time()+(365*24*60*60)); // 1 year
         
         // set session host
         $this->sesshost = $host;
                  
         // get session id(if some)
         $sessid = $_COOKIE['session'];
         
         // preform some session id validation (code lenght, validity of the session)
         if (isset($sessid) && strlen($sessid) == $this->codelength && $this->isSession($sessid))
         {
         	$this->sessid = $sessid;
         	
         	// check no expire
         	if ($_COOKIE['no_expire'] && $this->isNoExpire())
         	{
         		$noexpire = 1;
         	}
         	else 
         	{
         		$noexpire = 0;
         	}
         	
         	// update current session last action
         	$this->updSession($this->sessid, $noexpire);
         	
         	// load all session values
         	$this->listVals($this->sessid);
         }
         else 
         {
         	// start new session
         	$this->sessid = $this->startSession();
         }
         
         // get page referer
         if ($this->isVal('_current'))
         {
         	$this->setVal('_referer', $this->getVal('_current'));
         }
         
         // save current page
         $this->setVal('_current', $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']);
         
         // clear old sessions
         $this->clearSession();
	}
	
/**
 * @desc						:	start session
 * @return	$sessid	:	string	:	session id
 */
	
	function startSession()
	{		
		// session id
		$sessid = $this->genSessid();
		
		// generate sql record of sessions
		$qry  = 'INSERT INTO sessions ( s_id, s_lastact, s_ip ) ';
		$qry .= "VALUES ( '{$sessid}', '" . time() . "', '{$_SERVER['REMOTE_ADDR']}' )";
		
		$this->dbh->query($qry);
		
		// save session id to cookie and system session, in case cookies don't work
		setcookie('session', $sessid, false, '/', $this->sesshost);
		
		return $sessid;
	}
	
/**
 * @desc				:	end current session, destroing all it values
 * @return	:	boolean	:	status
 */
	function endSession()
	{
		// delete session sql record and it's values
		$this->dbh->delete(array('sessions', 'sessvalues'), "s_id='{$this->sessid}'");
				
		// detete session id from cookie and system session
		setcookie('session', '', time()-3600, '/', $this->sesshost);
		
		// unset session values within the class
		$this->sessid = null;
		$this->variables = null;
		
		return true;
	}
	
/**
 * @desc							:	update session last action
 * @param 	$sessid		:	string	:	session id
 * @param	$noexpire	:	int		:	is this not expire session
 * @return				:	boolean	:	status
 */
	function updSession($sessid=0, $noexpire=0)
	{
		$sessid = $sessid ? $sessid : $this->sessid;
		
		// check if this is no expire session
		if ($noexpire)
		{
			$time = $this->no_expire;
		} 
		else 
		{
			$time = time();
		}
		
		// update last action
		return $this->dbh->query("UPDATE sessions SET s_lastact='{$time}' WHERE s_id='{$sessid}' ");
	}

/**
 * @desc						:	check if session exists
 * @param 	$sessid	:	string	:	session id
 * @return 			:	boolean	:	is session exists
 */
	function isSession($sessid)
	{
		$this->dbh->query("SELECT s_id FROM sessions WHERE s_id='{$sessid}' LIMIT 1 ");
		
		return ($this->dbh->getnumrows() > 0 ? true : false );
	}

/**
 * @desc					:	clear expired sessions
 * @return 		:	boolean	:	status
 */
	function clearSession()
	{
		$time = time() - $this->max_idle;
		
		// select expired sessions
		$qry  = 'SELECT s_id AS id FROM sessions WHERE ';
		$qry .= "s_lastact < {$time}" ;
		
		$this->dbh->query($qry, 1);
		
		if ($this->dbh->getnumrows(1) == 0) { return true; }
		
		while ($row = $this->dbh->getrow(1)) 
		{			
			// delete sql record values			
			$this->dbh->query("DELETE FROM sessvalues WHERE s_id='{$row->id}' ");
		}
		
		// delete expired sql records
		$this->dbh->query("DELETE FROM sessions WHERE s_lastact < {$time}");
		
		return true;
	}
		
/**
 * @desc						:	generate random unique session id
 * @return	$sessid	:	string	:	session id
 */
	function genSessid()
	{
		$sessid = 0;
		
		// genereate random string
		mt_srand ((double) microtime() * 1000000);
		$puddle = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
		
		for($i=0; $i < $this->codelength - 1; $i++)
		{
			$sessid .= substr($puddle, (mt_rand()%(strlen($puddle))), 1);
		}
		
		// check if session id already exists
		if ($this->isSession($sessid))
		{
			$sessid = $this->genSessid();
		}
		
		return $sessid;
	}

/**
 * @desc								:	set value(s) to session
 * @param	$name	:	string/array	:	value name or array containig the values
 * @param 	$value	:	string			:	value
 * @return 			:	boolean			:	is setting succesful
 */
	function setVal($name, $value=0)
	{
		// if name is not array it is value name, so add a single value
		if (!is_array($name)) return $this->_setVal($name, $value);
		
		// else add a list of values
		foreach ($name as $key => $val)
		{
			if (!$this->_setVal($key, $val))
			{
				return false;
			}
		}
		
		return true;
	}
	
/**
 * @desc						:	set value to session
 * @param	$name	:	string	:	value name
 * @param 	$value	:	string	:	value
 * @return 			:	boolean	:	is setting succesful
 */
	function _setVal($name, $value)
	{
		// escape value
		$value	= addslashes($value);
		
		// check if value exists
		$this->dbh->query("SELECT s_id FROM sessvalues WHERE s_id='{$this->sessid}' AND sv_name='{$name}' LIMIT 1");
		
		if ($this->dbh->getnumrows() > 0)
		{
			// value exists, update it
			$qry  = 'UPDATE sessvalues SET ';
			$qry .= "sv_value='{$value}' WHERE s_id='{$this->sessid}' AND sv_name='{$name}'";
			
			if (!$this->dbh->query($qry)) { return false; }
		}
		else 
		{
			// if value don't exists add it
			$qry  = 'INSERT INTO sessvalues ( s_id, sv_name, sv_value ) ';
			$qry .= "VALUES ( '{$this->sessid}', '$name', '$value' )";
		
			if (!$this->dbh->query($qry)) { return false; }
		}
		
		// save the value 
		$this->variables[$name] = stripslashes($value);
		
		return true;
	}
	
/**
 * @desc							:	save this->variables to database
 * @return				:	boolean	:	is array added to database succesfully
 */
	function toDB()
	{
		foreach ($this->variables as $key => $val)
		{
			$this->setVal($key, $val);
		}
		
		return true;
	}
	
/**
 * @desc						:	delete session value
 * @param 	$name	:	string 	:	value name
 * @return 			:	boolean	:	is deleting succesful
 */
	function delVal($name=0)
	{
		// delete value
		$qry = "DELETE FROM sessvalues WHERE s_id='{$this->sessid}' ";
		
		if (func_num_args() > 1)
		{
			// get all functions arguments
			$args = func_get_args();
			
			// delete list of values
			$qry .= 'AND sv_name IN ( ';
			foreach ($args as $val)
			{
				$qry .= "'{$val}', ";
				
				// delete value from session variables
				unset($this->variables[$val]);
			}
			$qry  = rtrim($qry, ', ');
			$qry .= ') ';
		}
		elseif ($name)
		{
			// delete one value
			$qry .= "AND sv_name='{$name}' ";
			
			// delete value from session variables
			unset($this->variables[$name]);
		}
		else
		{
			// delete all values
			unset($this->variables);
		}
		
		return $this->dbh->query($qry);
	}
	
/**
 * @desc					:	clear all values which are not protected(_*)
 * @return		:	boolean	:	is clearing succesfull
 */
	function clearVal()
	{
		return $this->dbh->query("DELETE FROM sessvalues WHERE s_id='{$this->sessid}' WHERE sv_name NOT LIKE '_%' ");
	}

/**
 * @desc						:	check session value exists
 * @param 	$name	:	string 	:	value name
 * @return 			:	boolean	:	is session value exists
 */
	function isVal($name)
	{
		return isset($this->variables[$name]);
	}
	
/**
 * @desc						:	get session value
 * @param 	$name	:	string	:	variable name
 * @return 			:	unknown	:	variable
 */
	function getVal($name)
	{
		return $this->variables[$name];
	}
	
/**
 * @desc						:	get session value and then delete it
 * @param	$name	:	string	:	variable name
 * @return			:	uknow	:	variable
 */
	function cutVal($name)
	{
		
		if ($this->variables[$name])
		{
			$this->delVal($name);
		}
	
		return $this->variables[$name];
	}
	
/**
 * @desc						:	lsit session values
 * @param 	$sessid	:	string	:	session id
 * @return 			:	boolean	:	status
 */
	function listVals($sessid=0)
	{
		$sessid = $sessid ? $sessid : $this->sessid;
		
		$this->dbh->query("SELECT sv_name, sv_value FROM sessvalues WHERE s_id='{$sessid}' ");
		
		$this->variables = array();
		while ($row = $this->dbh->getrow()) 
		{
			$this->variables[$row->sv_name] = stripslashes($row->sv_value);
		}
		
		return true;
	}
/**
 * @desc				:	check if this is no expire session
 * @return 	:	boolean	:	is this no expire session
 */
	function isNoExpire()
	{
		$cookie = $_COOKIE['noexpire'];
		$parts = explode('::', $this->variables['noexpire_str']);
		
		if ($_SERVER['REMOTE_ADDR'] == $parts[0] && $cookie == $parts[1])
		{
			return true;
		}
		
		return false;
	}
	
/**
 * @desc	:	makes current session no expire
 * @note 	:	this work only with cookies available
 */
	function setNoExpire()
	{
		// generate random id, using genSessid function
		$randid = $this->genSessid();
		
		// generate sring by current ip and the random id
		$string = $_SERVER['REMOTE_ADDR'] . '::' . $randid;
		
		// save no expire string
		$this->setVal('noexpire_str', $string);
		
		// set the never expiring cookies
		setcookie('noexpire', $randid, $this->no_expire, '/', $this->sesshost);
		setcookie('session', $this->sessid, $this->no_expire, '/', $this->sesshost);
	}
	
/**
 * @desc						:	count activ sessions
 * @param	$fld	:	string	:	count by field name
 * @param	$last	:	int		:	last action (in seconds)
 * @return			:	int		:	sessions count
 */
	function count($fld=0, $last=600)
	{
		if (!$fld)
		{
			$qry  = "SELECT s_id FROM sessions WHERE s_lastact > " . ( time() - $last );
			$qry .= " GROUP BY s_ip ";
			
			$this->dbh->query($qry);
			
			return $this->dbh->getnumrows();
		}
		
		$qry  = "SELECT a.s_id FROM sessions a, sessvalues b ";
		$qry .= "WHERE s_lastact > " . ( time() - $last );
		$qry .= " AND a.s_id = b.s_id AND b.sv_name='{$fld}' ";
		$qry .= "GROUP BY a.s_ip ";
		
		$this->dbh->query($qry);
		
		return $this->dbh->getnumrows();
	}
	
/**
 * @desc	:	return to page referer
 * 
 */
	function back()
	{
		if ($_SERVER['HTTP_REFERER'])
		{
			header("location: {$_SERVER['HTTP_REFERER']}");
			exit;
		}
		
		header('location: http://' . $this->getVal('_referer'));
		exit;
	}
	
/**
 * @desc						:	add message
 * @param	$value	:	string	:	message text, value
 * @param	$name	:	string	:	message name, topic
 * 
 */
	function add_msg($value, $name=false)
	{
		// add message
		if ($name)
		{
			// add in message array $name as key
			$this->messages[$name] = $value;
		}
		else
		{
			// add message just as next array value
			$this->messages[] = $value;
		}
	}

/**
 * @desc	:	clear all messages
 *
 */
	function clear_msg()
	{
		// 'restart' $messages array
		$this->messages = array();
	}
	
/**
 * @desc	:	check if there is at least one message
 *
 */
	function is_msg()
	{
		if (count($this->messages) > 0)
		{
			return true;
		}
		
		return false;
	}
	
/**
 * @desc							:	throw messages to some page
 * @param	$message	:	string	:	message to send (if set message type is 2); 
 * @param	$redirect	:	string	:	redirect link (def: HTTP_REFERER)
 */
	function throw_msg($message=0, $redirect=0)
	{
		// prepare message(s) string for session
		if (!$message)
		{
			//set message type
			$type = 1;
				
			// seriazle messages
			$message = serialize($this->messages);
		}
		$message = addslashes($message);
		
		// save message(s) in session	
		$this->setVal(array(
							'_sysmtype'	=> $type,
							'_sysmsg'	=> $message
							));
								
		// redirect
		if ($redirect)
		{
			header("location: {$redirect}");
			exit;
		}
		
		// [else] goto to referer
		$this->back();
	}
	
/**
 * @desc									:	catch message(s) 
 * @return	$message	:	string/array	:	the message(s) (if some)
 * 
 */
	function catch_msg()
	{
		// check if there is registered message
		if (!$this->isVal('_sysmsg'))
		{
			return false;
		}
		
		// recover message type and message value(s) from session and then delete them
		$mtype		= $this->cutVal('_sysmtype');
		$message	= $this->cutVal('_sysmsg');
		$message	= stripslashes($message);
		
		// check if message is serialized array
		if ($mtype == 1)
		{
			$message = unserialize($message);
		}
			
		// return the message
		return $message;
	}
}

?>
Return current item: Jack's Session class