123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- <?php
- /**
- * 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 ;
- *
- * @package Kohana/Database
- * @category Session
- * @author Kohana Team
- * @copyright (c) Kohana Team
- * @license https://koseven.ga/LICENSE.md
- */
- class Kohana_Session_Database extends Session {
- // Database instance
- protected $_db;
- // Database table name
- protected $_table = 'sessions';
- // Database column names
- protected $_columns = [
- 'session_id' => 'session_id',
- 'last_active' => 'last_active',
- 'contents' => 'contents'
- ];
- // Garbage collection requests
- protected $_gc = 500;
- // The current session id
- protected $_session_id;
- // The old session id
- protected $_update_id;
- 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 (random_int(0, $this->_gc) === $this->_gc)
- {
- // Run garbage collection
- // This will average out to run once every X requests
- $this->_gc();
- }
- }
- public function id()
- {
- return $this->_session_id;
- }
- 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;
- }
- 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('', TRUE));
- // Get the the id from the database
- $result = $query->execute($this->_db);
- }
- while ($result->count());
- return $this->_session_id = $id;
- }
- 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;
- }
- /**
- * @return bool
- */
- protected function _restart()
- {
- $this->_regenerate();
- return TRUE;
- }
- 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);
- }
- } // End Session_Database
|