Database-based session class.
Sample schema:
CREATE TABLE `sessions` (
`session_id` VARCHAR( 24 ) NOT NULL,
`last_active` INT UNSIGNED NOT NULL,
`contents` TEXT NOT NULL,
PRIMARY KEY ( `session_id` ),
INDEX ( `last_active` )
) ENGINE = MYISAM ;
Class declared in MODPATH/database/classes/Session/Database.php on line 3.
string
$defaultdefault session adapter
string(6) "native"
array
$instancessession instances
array(0)
$_columnsarray(3) ( "session_id" => string(10) "session_id" "last_active" => string(11) "last_active" "contents" => string(8) "contents" )
array
$_datasession data
array(0)
$_dbNULL
bool
$_destroyedsession destroyed?
bool FALSE
bool
$_encryptedencrypt session data?
bool FALSE
$_gcinteger 500
int
$_lifetimecookie lifetime
integer 0
string
$_namecookie name
string(7) "session"
$_session_idNULL
$_tablestring(8) "sessions"
$_update_idNULL
Overloads the name, lifetime, and encrypted session settings.
Sessions can only be created using the Session::instance method.
array
$config
= NULL - Configuration string
$id
= NULL - Session id void
public function __construct(array $config = null, $id = null)
{
if (!isset($config['group'])) {
// Use the default group
$config['group'] = Database::$default;
}
// Load the database
$this->_db = Database::instance($config['group']);
if (isset($config['table'])) {
// Set the table name
$this->_table = (string) $config['table'];
}
if (isset($config['gc'])) {
// Set the gc chance
$this->_gc = (int) $config['gc'];
}
if (isset($config['columns'])) {
// Overload column names
$this->_columns = $config['columns'];
}
parent::__construct($config, $id);
if (mt_rand(0, $this->_gc) === $this->_gc) {
// Run garbage collection
// This will average out to run once every X requests
$this->_gc();
}
}
Get the current session id, if the session supports it.
$id = $session->id();
Not all session types have ids.
string
public function id()
{
return $this->_session_id;
}
Session object is rendered to a serialized string. If encryption is enabled, the session will be encrypted. If not, the output string will be encoded.
echo $session;
string
public function __toString()
{
// Serialize the data array
$data = $this->_serialize($this->_data);
if ($this->_encrypted) {
// Encrypt the data using the default key
$data = Encrypt::instance($this->_encrypted)->encode($data);
} else {
// Encode the data
$data = $this->_encode($data);
}
return $data;
}
Returns the current session array. The returned array can also be assigned by reference.
// Get a copy of the current session data
$data = $session->as_array();
// Assign by reference for modification
$data =& $session->as_array();
array
public function & as_array()
{
return $this->_data;
}
Set a variable by reference.
$session->bind('foo', $foo);
string
$key
required - Variable name byref mixed
$value
required - Referenced value $this
public function bind($key, & $value)
{
$this->_data[$key] = & $value;
return $this;
}
Removes a variable in the session array.
$session->delete('foo');
string
$key
required - ,... variable name $this
public function delete($key)
{
$args = func_get_args();
foreach ($args as $key) {
unset($this->_data[$key]);
}
return $this;
}
Completely destroy the current session.
$success = $session->destroy();
boolean
public function destroy()
{
if ($this->_destroyed === false) {
if ($this->_destroyed = $this->_destroy()) {
// The session has been destroyed, clear all data
$this->_data = [];
}
}
return $this->_destroyed;
}
Get a variable from the session array.
$foo = $session->get('foo');
string
$key
required - Variable name mixed
$default
= NULL - Default value to return mixed
public function get($key, $default = null)
{
return array_key_exists($key, $this->_data) ? $this->_data[$key] : $default;
}
Get and delete a variable from the session array.
$bar = $session->get_once('bar');
string
$key
required - Variable name mixed
$default
= NULL - Default value to return mixed
public function get_once($key, $default = null)
{
$value = $this->get($key, $default);
unset($this->_data[$key]);
return $value;
}
Creates a singleton session of the given type. Some session types (native, database) also support restarting a session by passing a session id as the second parameter.
$session = Session::instance();
Session::write will automatically be called when the request ends.
string
$type
= NULL - Type of session (native, cookie, etc) string
$id
= NULL - Session identifier Session
public static function instance($type = null, $id = null)
{
if ($type === null) {
// Use the default type
$type = Session::$default;
}
if (!isset(Session::$instances[$type])) {
// Load the configuration for this type
$config = Kohana::$config->load('session')->get($type);
// Set the session class name
$class = 'Session_' . ucfirst($type);
// Create a new session instance
Session::$instances[$type] = $session = new $class($config, $id);
// Write the session at shutdown
register_shutdown_function([$session, 'write']);
}
return Session::$instances[$type];
}
Get the current session cookie name.
$name = $session->name();
string
public function name()
{
return $this->_name;
}
Loads existing session data.
$session->read();
string
$id
= NULL - Session id void
public function read($id = null)
{
$data = null;
try {
if (is_string($data = $this->_read($id))) {
if ($this->_encrypted) {
// Decrypt the data using the default key
$data = Encrypt::instance($this->_encrypted)->decode($data);
} else {
// Decode the data
$data = $this->_decode($data);
}
// Unserialize the data
$data = $this->_unserialize($data);
} else {
// Ignore these, session is valid, likely no data though.
}
} catch (Exception $e) {
// Error reading the session, usually a corrupt session.
throw new Session_Exception('Error reading session data.', null, Session_Exception::SESSION_CORRUPT);
}
if (is_array($data)) {
// Load the data locally
$this->_data = $data;
}
}
Generates a new session id and returns it.
$id = $session->regenerate();
string
public function regenerate()
{
return $this->_regenerate();
}
Restart the session.
$success = $session->restart();
boolean
public function restart()
{
if ($this->_destroyed === false) {
// Wipe out the current session.
$this->destroy();
}
// Allow the new session to be saved
$this->_destroyed = false;
return $this->_restart();
}
Set a variable in the session array.
$session->set('foo', 'bar');
string
$key
required - Variable name mixed
$value
required - Value $this
public function set($key, $value)
{
$this->_data[$key] = $value;
return $this;
}
Sets the last_active timestamp and saves the session.
$session->write();
Any errors that occur during session writing will be logged, but not displayed, because sessions are written after output has been sent.
boolean
public function write()
{
if (headers_sent() OR $this->_destroyed) {
// Session cannot be written when the headers are sent or when
// the session has been destroyed
return false;
}
// Set the last active timestamp
$this->_data['last_active'] = time();
try {
return $this->_write();
} catch (Exception $e) {
// Log & ignore all errors when a write fails
Kohana::$log->add(Log::ERROR, Kohana_Exception::text($e))->write();
return false;
}
}
Destroys the current session.
boolean
protected function _destroy()
{
if ($this->_update_id === null) {
// Session has not been created yet
return true;
}
// Delete the current session
$query = DB::delete($this->_table)
->where($this->_columns['session_id'], '=', ':id')
->param(':id', $this->_update_id);
try {
// Execute the query
$query->execute($this->_db);
// Delete the old session id
$this->_update_id = null;
// Delete the cookie
Cookie::delete($this->_name);
} catch (Exception $e) {
// An error occurred, the session has not been deleted
return false;
}
return true;
}
protected function _gc()
{
if ($this->_lifetime) {
// Expire sessions when their lifetime is up
$expires = $this->_lifetime;
} else {
// Expire sessions after one month
$expires = Date::MONTH;
}
// Delete all sessions that have expired
DB::delete($this->_table)
->where($this->_columns['last_active'], '<', ':time')
->param(':time', time() - $expires)
->execute($this->_db);
}
Loads the raw session data string and returns it.
string
$id
= NULL - Session id string
protected function _read($id = null)
{
if ($id OR $id = Cookie::get($this->_name)) {
$result = DB::select([$this->_columns['contents'], 'contents'])
->from($this->_table)
->where($this->_columns['session_id'], '=', ':id')
->limit(1)
->param(':id', $id)
->execute($this->_db);
if ($result->count()) {
// Set the current session id
$this->_session_id = $this->_update_id = $id;
// Return the contents
return $result->get('contents');
}
}
// Create a new session id
$this->_regenerate();
return null;
}
Generate a new session id and return it.
string
protected function _regenerate()
{
// Create the query to find an ID
$query = DB::select($this->_columns['session_id'])
->from($this->_table)
->where($this->_columns['session_id'], '=', ':id')
->limit(1)
->bind(':id', $id);
do {
// Create a new session id
$id = str_replace('.', '-', uniqid(null, true));
// Get the the id from the database
$result = $query->execute($this->_db);
} while ($result->count());
return $this->_session_id = $id;
}
bool
protected function _restart()
{
$this->_regenerate();
return true;
}
Writes the current session.
boolean
protected function _write()
{
if ($this->_update_id === null) {
// Insert a new row
$query = DB::insert($this->_table, $this->_columns)
->values([':new_id', ':active', ':contents']);
} else {
// Update the row
$query = DB::update($this->_table)
->value($this->_columns['last_active'], ':active')
->value($this->_columns['contents'], ':contents')
->where($this->_columns['session_id'], '=', ':old_id');
if ($this->_update_id !== $this->_session_id) {
// Also update the session id
$query->value($this->_columns['session_id'], ':new_id');
}
}
$query
->param(':new_id', $this->_session_id)
->param(':old_id', $this->_update_id)
->param(':active', $this->_data['last_active'])
->param(':contents', $this->__toString());
// Execute the query
$query->execute($this->_db);
// The update and the session id are now the same
$this->_update_id = $this->_session_id;
// Update the cookie with the new session id
Cookie::set($this->_name, $this->_session_id, $this->_lifetime);
return true;
}
Decodes the session data using base64_decode.
string
$data
required - Data string
protected function _decode($data)
{
return base64_decode($data);
}
Encodes the session data using base64_encode.
string
$data
required - Data string
protected function _encode($data)
{
return base64_encode($data);
}
Serializes the session data.
array
$data
required - Data string
protected function _serialize($data)
{
return serialize($data);
}
Unserializes the session data.
string
$data
required - Data array
protected function _unserialize($data)
{
return unserialize($data);
}