-
Notifications
You must be signed in to change notification settings - Fork 0
NDB Session Class
Category:Session Category:Libraries::Session Category:Contributions::Libraries::PHP
[h2] NDB Session Class for CodeIgniter - Version 1.2[/h2] [h2](Last update 24.06.2011)[/h2]
Native Session makes good use of PHP’s native session handling abilities, but it does not allow the use of a database for session storage. Saving user session data into database is more secure on any type of hosting (Shared ... ). This library overwrites normal native sassion functions too save user data directly into database and gives us some extra functions over CI Session.
[b]Follow on BitBucket: [/b] LINK.
[b]Follow on CodeIgniter Forum:[/b] LINK.
[b]Download on BitBucket: [/b] LINK.
[h2]Overview[/h2]
- Is based on Native Session but has database functionality built in.
- Cmpatible with CodeIgniter 1.7 +.
- Drop-in replacement for CI’s Session library.
- Config options and flash data are supported but not ession encryption.
- When using with a database, only the session_id is stored in a cookie. Any other data is stored in the database (Nativly would be stored to server ).
- Tested IE6, IE7, IE8, IE9, Firefox 4, Chrome
- PHP5+
[h2]Usage[/h2]
[b]Same usage as CI Session + Extras:[/b] LINK.
[b]Extras:[/b]
- Access data from database: [code] $_SESSION['Data]; [/code]
- Write data to database: [code] $_SESSION['Data'] = 'Value'; [/code]
[h2]Install[/h2]
- Download Session Class and copy it to "appliaction/libraries/"
- Insert new database table for Session storage
- Autoload or load CI database Class and Session Class
- Don't forget to setup database configuration
- Have fun
[h2]Differences between NDB Session and Native Session[/h2]
- Session ID only in cookie and no user data
- Saving user data to database and not to server
- Regenerating session id every X min
- Keeping track of session expiration and session time to update
- OOP Approach
[h2]Differences between NDB Session and CI Session[/h2]
- Using native PHP Session functions ( Smaller lib. same security )
- No encryption of cookie as only Session ID is stored in cookie (Allready hashed)
- Checking valid Session ID differently ( We dont save IP, Useragent, Activity to an cookie)
- Session garbage collector works differently ( Expired data, Useless data)
- After session destroy we create new empty session so u can set new Session data after it
- Some CI Session functions removed as not needet (Functions which PHP does it for us)
- Extras for setting and accessing Session data( $_SESSION['data'] ...)
[h2]Required Database Structure[/h2]
[code]
CREATE TABLE IF NOT EXISTS Sessions
(
session_id
varchar(40) collate utf8_bin NOT NULL default '0',
ip_address
varchar(16) collate utf8_bin NOT NULL default '0',
user_agent
varchar(50) collate utf8_bin NOT NULL,
last_activity
int(10) unsigned NOT NULL default '0',
user_data
text collate utf8_bin NOT NULL,
PRIMARY KEY (session_id
)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
[/code]
[h2]Example Configuration (/system/application/config/config.php)[/h2]
[code] $config['sess_cookie_name'] = 'ci_session'; $config['sess_expiration'] = 3600; // 1 H $config['sess_expire_on_close'] = FALSE; $config['sess_encrypt_cookie'] = FALSE; $config['sess_use_database'] = TRUE; $config['sess_table_name'] = 'Sessions'; $config['sess_match_ip'] = TRUE; $config['sess_match_useragent'] = TRUE; $config['sess_time_to_update'] = 300; // 5 min
$config['cookie_prefix'] = ''; $config['cookie_domain'] = '.URI.com'; $config['cookie_path'] = '/'; [/code]
[h2]Code[/h2]
[code] <?php
if(!defined('BASEPATH')) exit('No direct script access allowed');
/**
-
|==========================================================
-
| LIBRARY: CI_Session
-
|==========================================================
-
|
-
| Custom Session library.
-
|
-
| @subpackage Libraries
-
| @category Libraries
-
| @since Version 1.2
-
| @author Denis Molan Dev
-
| @copyright Copyright (c) 2011, Denis Molan
-
| @license http://www.spletna-evolucija.com
-
| @link http://www.spletna-evolucija.com
-
| */ class CI_Session{
var $sess_table_name = ''; var $sess_expiration = 7200; // 2 H var $expire = 0; var $expire_id = 0; var $sess_time_to_update = 300; // 5 min var $sess_match_ip = TRUE; var $sess_match_useragent = TRUE; var $time_reference = 'time'; var $sess_cookie_name = 'ci_session'; var $cookie_prefix = ''; var $cookie_path = '/'; var $cookie_domain = ''; var $cookie_secure = FALSE; var $flashdata_key = 'flash'; var $user_ip; var $user_useragent; var $user_time; var $CI;
/**
-
|==========================================================
-
| FUNCTION: __construct
-
|==========================================================
-
|
-
| Constructor.
-
|
-
| @access private
-
| @return void
-
| */ function __construct(){ log_message('debug', "Session Class Initialized"); $this->CI = & get_instance();
// Loading CI config file or using default settings foreach(array('sess_table_name', 'sess_expiration', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'cookie_secure', 'sess_time_to_update', 'time_reference', 'cookie_prefix') as $key){ $this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key); }
//Database class must be loaded and table name for session must be set if($this->sess_table_name != ''){ $this->CI->load->database(); }else{ show_error('In order to use the Session class you need to setup database class.'); }
// Set the cookie name $this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name; // Detecting user preferences which will need later $this->user_ip = $this->CI->input->ip_address(); $this->user_useragent = substr($this->CI->input->user_agent(), 0, 50); $this->user_time = time();
// If session expiration not set we set it to 1 month if($this->sess_expiration == 0){ $this->sess_expiration = (7200); // 2 h } $this->expire = $this->user_time - $this->sess_expiration; $this->expire_id = $this->user_time - $this->sess_time_to_update;
// Client side session cookie name which contains only session id session_name($this->sess_cookie_name); session_set_cookie_params($this->sess_expiration, $this->cookie_path, $this->cookie_domain, false, false); // Overwriting normal session functions with our own -> userdata goes into database session_set_save_handler( array(&$this, '_sess_open'), array(&$this, '_sess_close'), array(&$this, '_sess_read'), array(&$this, '_sess_write'), array(&$this, 'sess_destroy'), array(&$this, '_sess_gc') );
// Session starts starts session and generate or use session id (Client side cookie)
session_start(); // Updating session ID every X min $this->_sess_update(); // Codeigniter flashdata manage $this->_flashdata_sweep(); $this->_flashdata_mark(); log_message('debug', "Session routines successfully run"); }
/**
- |==========================================================
- | FUNCTION: __destruct
- |==========================================================
- |
- | Destructor.
- |
- | @access private
- | @return void
- | */ function __destruct(){ session_write_close(); }
/**
- |==========================================================
- | FUNCTION: _sess_open
- |==========================================================
- |
- | We dont need as saving data into database via CI Database
- | Open is first called after session_start
- |
- | @access private
- | @return bool
- | */ function _sess_open(){ return true; }
/**
- |==========================================================
- | FUNCTION: _sess_close
- |==========================================================
- |
- | Session closed will chech garbage.
- |
- | @access private
- | @return bool
- | */ function _sess_close(){ $this->_sess_gc(); return true; }
/**
-
|==========================================================
-
| FUNCTION: _sess_read
-
|==========================================================
-
|
-
| Read is second called after session_start, using it for reading data from database.
-
| If session does not exist we must return '' and if it does we return data.
-
|
-
| @access private
-
| @param string session id auto given into function
-
| @return string
-
| */ function _sess_read($sess_id){ $this->CI->db->start_cache(); $this->CI->db->select('user_data'); $this->CI->db->where('session_id', $sess_id); $this->CI->db->where('ip_address', $this->user_ip); $this->CI->db->where("last_activity > ".$this->expire); if($this->sess_match_useragent == TRUE) $this->CI->db->where('user_agent', $this->user_useragent); $this->CI->db->stop_cache();
if($this->CI->db->count_all_results($this->sess_table_name) == 0){ $this->CI->db->flush_cache(); return ''; }else{ $row = $this->CI->db->get($this->sess_table_name)->row(); $this->CI->db->flush_cache(); return (isset($row->user_data) AND $row->user_data != '') ? $row->user_data : ''; } }
/**
-
|==========================================================
-
| FUNCTION: _sess_write
-
|==========================================================
-
|
-
| Updating user data in database
-
|
-
| @access private
-
| @param string session id auto given into function
-
| @param mixed session user data
-
| @return bool
-
| */ function _sess_write($sess_id, $sess_data){ $this->CI->db->start_cache(); $this->CI->db->where('session_id', $sess_id); $this->CI->db->where('ip_address', $this->user_ip); $this->CI->db->where("last_activity > ".$this->expire); if($this->sess_match_useragent == TRUE) $this->CI->db->where('user_agent', $this->user_useragent); $this->CI->db->stop_cache();
if($this->CI->db->count_all_results($this->sess_table_name) == 0){ $status = $this->_sess_create($sess_id, $sess_data); }else{ $status = $this->CI->db->update($this->sess_table_name, array('user_data' => $sess_data)); } $this->CI->db->flush_cache(); return $status; }
/**
-
|==========================================================
-
| FUNCTION: sess_destroy
-
|==========================================================
-
|
-
| removing session cookie and database data.
-
|
-
| @access public
-
| @param string session id given automaticly or in CI not
-
| @return void
-
| */ function sess_destroy($sess_id = ''){ if(!isset($sess_id) || $sess_id == ''){ $sess_id = session_id(); } session_unset();
$this->CI->db->where('session_id', $sess_id); $this->CI->db->where('ip_address', $this->user_ip); if($this->sess_match_useragent == TRUE) $this->CI->db->where('user_agent', $this->user_useragent); $status = $this->CI->db->delete($this->sess_table_name); $this->_sess_create(); return $status; }
/**
- |==========================================================
- | FUNCTION: _sess_gc
- |==========================================================
- |
- | Called automaticly and manualy. Removing old sessions when expired.
- | Removing also data which didnt yet expire but useless
- | (Situation when user dont logout close browser window and comeback -> new session created
- | and old stay behind )
- |
- | @access private
- | @return void
- | */ function _sess_gc(){ $this->CI->db->where("last_activity < ", $this->expire); $this->CI->db->or_where("session_id !=", session_id()); $this->CI->db->where("ip_address", $this->user_ip); if($this->sess_match_useragent == TRUE) $this->CI->db->where('user_agent', $this->user_useragent); $status = $this->CI->db->delete($this->sess_table_name); return $status; }
/**
-
|==========================================================
-
| FUNCTION: _sess_create
-
|==========================================================
-
|
-
| Creating new session if not exist or after destroy.
-
|
-
| @access private
-
| @param string session id
-
| @param string session data
-
| @return void
-
| */ function _sess_create($sess_id = '', $sess_data = ''){ if($sess_id == ''){ session_regenerate_id(); $sess_id = $this->CI->db->escape_str(session_id()); $sess_data = ''; }
$data = array( 'session_id' => $sess_id, 'ip_address' => $this->user_ip, 'user_agent' => $this->user_useragent, 'last_activity' => $this->user_time, 'user_data' => $sess_data ); $status = $this->CI->db->insert($this->sess_table_name, $data); return $status; }
/**
-
|==========================================================
-
| FUNCTION: _sess_last_updated
-
|==========================================================
-
|
-
| Updating session id after X min specified by user it self.
-
| We check session garbage also that we dont do it every request.
-
|
-
| @access private
-
| @return void
-
| */ function _sess_update(){ $old_id = session_id(); // Checking if user session should be updated $this->CI->db->start_cache(); $this->CI->db->where('session_id', $old_id); $this->CI->db->where('ip_address', $this->user_ip); if($this->sess_match_useragent == TRUE) $this->CI->db->where('user_agent', $this->user_useragent); $this->CI->db->where("last_activity < ".$this->expire_id); $this->CI->db->stop_cache();
if($this->CI->db->count_all_results($this->sess_table_name) == 1){ // FALSE because we dont wanna delete data in database just update it session_regenerate_id(FALSE); $new_id = session_id(); $status = $this->CI->db->update($this->sess_table_name, array('session_id' => $new_id, 'last_activity' => $this->user_time)); }else{ $status = FALSE; } $this->CI->db->flush_cache(); return $status; }
/**
- |==========================================================
- | FUNCTIONS: CI_Session modified functions
- |==========================================================
- | */ function userdata($item){ return (!isset($_SESSION[$item])) ? FALSE : $_SESSION[$item]; }
function set_userdata($newdata = array(), $newval = ''){ if(is_string($newdata)){ $newdata = array($newdata => $newval); }
if(count($newdata) > 0){ foreach($newdata as $key => $val){ $_SESSION[$key] = $val; } }
}
function unset_userdata($newdata = array()){ if(is_string($newdata)){ $newdata = array($newdata => ''); }
if(count($newdata) > 0){ foreach($newdata as $key => $val){ unset($_SESSION[$key]); } }
}
function _flashdata_mark(){ foreach($_SESSION as $name => $value){ $parts = explode(':new:', $name); if(is_array($parts) && count($parts) === 2){ $new_name = $this->flashdata_key.':old:'.$parts[1]; $this->set_userdata($new_name, $value); $this->unset_userdata($name); } } }
function _flashdata_sweep(){ foreach($_SESSION as $key => $value){ if(strpos($key, ':old:')){ $this->unset_userdata($key); } } }
/**
-
|==========================================================
-
| FUNCTIONS: CI_Session functions not modified
-
|==========================================================
-
| */ function set_flashdata($newdata = array(), $newval = ''){ if(is_string($newdata)){ $newdata = array($newdata => $newval); }
if(count($newdata) > 0){ foreach($newdata as $key => $val){ $flashdata_key = $this->flashdata_key.':new:'.$key; $this->set_userdata($flashdata_key, $val); } } }
function keep_flashdata($key){ $old_flashdata_key = $this->flashdata_key.':old:'.$key; $value = $this->userdata($old_flashdata_key);
$new_flashdata_key = $this->flashdata_key.':new:'.$key; $this->set_userdata($new_flashdata_key, $value);
}
function flashdata($key){ $flashdata_key = $this->flashdata_key.':old:'.$key; return $this->userdata($flashdata_key); }
/**
- |==========================================================
- | END
- |==========================================================
- | */
-
}
/* USEFULL INFO
Called: session_start():
- open
- read
- clean (if cleaning is being done this call)
- write
- close
Called session_destroy():
- open
- read
- clean (if cleaning is being done this call)
- destroy
- close
Called session_regenerate_id(1):
- open
- read
- clean (if cleaning is being done this call)
- destroy
- write
- close */ [/code]