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
$defaultlink to thisdefault session adapter
string(6) "native"
array
$instanceslink to thissession instances
array(0)
$_columnslink to thisarray(3) ( "session_id" => string(10) "session_id" "last_active" => string(11) "last_active" "contents" => string(8) "contents" )
array
$_datalink to thissession data
array(0)
$_dblink to thisNULL
bool
$_destroyedlink to thissession destroyed?
bool FALSE
bool
$_encryptedlink to thisencrypt session data?
bool FALSE
$_gclink to thisinteger 500
int
$_lifetimelink to thiscookie lifetime
integer 0
string
$_namelink to thiscookie name
string(7) "session"
$_session_idlink to thisNULL
$_tablelink to thisstring(8) "sessions"
$_update_idlink to thisNULL
Overloads the name, lifetime, and encrypted session settings.
Sessions can only be created using the Session::instance method.
array
$config
= NULL - Configurationstring
$id
= NULL - Session idvoid
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 namebyref 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 =
array
();
}
}
return
$this
->_destroyed;
}
Get a variable from the session array.
$foo
=
$session
->get(
'foo'
);
string
$key
required - Variable namemixed
$default
= NULL - Default value to returnmixed
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 namemixed
$default
= NULL - Default value to returnmixed
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 identifierSession
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(
array
(
$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 idvoid
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 namemixed
$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 idstring
protected
function
_read(
$id
= NULL)
{
if
(
$id
OR
$id
= Cookie::get(
$this
->_name))
{
$result
= DB::select(
array
(
$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(
array
(
':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 - Datastring
protected
function
_decode(
$data
)
{
return
base64_decode
(
$data
);
}
Encodes the session data using base64_encode.
string
$data
required - Datastring
protected
function
_encode(
$data
)
{
return
base64_encode
(
$data
);
}
Serializes the session data.
array
$data
required - Datastring
protected
function
_serialize(
$data
)
{
return
serialize(
$data
);
}
Unserializes the session data.
string
$data
required - Dataarray
protected
function
_unserialize(
$data
)
{
return
unserialize(
$data
);
}