CI Framework session.php Source Analysis _php Instance

Source: Internet
Author: User
Tags md5 hash set cookie setcookie
CI session is not the original session, is my previous cookie based session, in addition, CI can be configured according to the user choose whether the session into the database, I like this function, there is "flash data" function, The flash data is only available for the next server request and is then automatically cleared. Common use methods are:

$this->session->set_userdata (' some_name ', ' some_value '); Set session data

$this->session->userdata (' item '); Get Session data

$this->session->unset_userdata (' some_name '); Delete session data

$this->session->sess_destroy (); Destroying session data

$this->session->set_flashdata (' Item ', ' value '); Setting up Flash Data

$this->session->flashdata (' item '); Get Flash Data

$this->session->keep_flashdata (' item '); Preserve Flash Data

Copy CodeThe code is as follows:
/**
* CI is session based cookie
*/
Class Ci_session {
var $sess _encrypt_cookie = FALSE; Whether to encrypt session
var $sess _use_database = FALSE; Whether the session is stored in the database
var $sess _table_name = "; The table name in which the session is stored
var $sess _expiration = 7200; Expiration time of Session
var $sess _expire_on_close = FALSE; Whether the session expires automatically when the browser window is closed
var $sess _match_ip = false;//Whether the session data is read by the user's IP address
var $sess _match_useragent = TRUE; Whether to follow the corresponding User Agent to read the session data.
var $sess _cookie_name = ' ci_session '; Cookie Name
var $cookie _prefix = "; Cookie Prefix
var $cookie _path = "; Cookie Path
var $cookie _domain = "; Cookie Scope
var $cookie _secure = FALSE; is valid under secure HTTPS protocol
var $sess _time_to_update = 300; How often session cookies are updated
var $encryption _key = "; Encrypt key
var $flashdata _key = ' flash ';
var $time _reference = ' time ';
var $gc _probability = 5; Ability to recycle session
var $userdata = array (); User session Data Save variables
var $CI; CI Super handle
var $now; Current time
Public function __construct ($params = Array ())
{
Log_message (' Debug ', ' Session Class Initialized ');
Get CI Super class
$this->ci =& get_instance ();
Getting configuration data from the config file
foreach (Array (' Sess_encrypt_cookie ', ' sess_use_database ', ' sess_table_name ', ' sess_expiration ', ' Sess_expire_on_ Close ', ' sess_match_ip ', ' sess_match_useragent ', ' sess_cookie_name ', ' cookie_path ', ' cookie_domain ', ' cookie_secure ' , ' sess_time_to_update ', ' time_reference ', ' cookie_prefix ', ' Encryption_key ') as $key)
{
$this $key = (Isset ($params [$key]))? $params [$key]: $this->ci->config->item ($key);
}
Encryption_key must be set
if ($this->encryption_key = = ")
{
Show_error (' In order ', the Session class you is required to set a encryption key in your config file. ');
}
Load String helper function
$this->ci->load->helper (' string ');
D If the cookie is encrypted, the encryption class is introduced
if ($this->sess_encrypt_cookie = = TRUE)
{
$this->ci->load->library (' encrypt ');
}
If the session is counted into the database, the DB is introduced
if ($this->sess_use_database = = = TRUE and $this->sess_table_name! = ")
{
$this->ci->load->database ();
}
Get current time
$this->now = $this->_get_time ();
If the session is not set to a valid time, the default is two years
if ($this->sess_expiration = = 0)
{
$this->sess_expiration = (60*60*24*365*2);
}
Get Cookie Name
$this->sess_cookie_name = $this->cookie_prefix. $this->sess_cookie_name;
If the session does not exist, create a new session
if (! $this->sess_read ())
{
$this->sess_create ();
}
Else
{
$this->sess_update ();
}
Flash mark old Flash data
$this->_flashdata_sweep ();
Data that marks new flash data as old with old will flash on the next request
$this->_flashdata_mark ();
Recycle/Delete Expired session
$this->_sess_gc ();
Log_message (' Debug ', ' Session routines successfully run ');
}
// --------------------------------------------------------------------
/**
* Read session data
*/
function Sess_read ()
{
Get session
$session = $this->ci->input->cookie ($this->sess_cookie_name);
No session, bye.
if ($session = = = FALSE)
{
Log_message (' Debug ', ' A session cookie ' is not found. ');
return FALSE;
}
If a cookie is encrypted
if ($this->sess_encrypt_cookie = = TRUE)
{
$session = $this->ci->encrypt->decode ($session);
}
Else
{
Encryption is not used, so we need to check the MD5 hash
$hash = substr ($session, strlen ($session)-32); Get last Chars
$session = substr ($session, 0, strlen ($session)-32);
Does The MD5 hash match? This was to prevent manipulation of the session data in userspace
if ($hash!== MD5 ($session. $this->encryption_key))
{
Log_message (' Error ', ' The session cookie, ' data did not match ' and ' expected '. This could is a possible hacking attempt. ');
$this->sess_destroy ();
return FALSE;
}
}
Deserializing the session array stored in the cookie
$session = $this->_unserialize ($session);
Detecting session data
if (! Is_array ($session) or! isset ($session [' session_id ']) or! isset ($session [' ip_address ']) or! isset ($session [' User_ Agent ']) OR! Isset ($session [' last_activity ']))
{
$this->sess_destroy ();
return FALSE;
}
is the session data out of date?
if ($session [' last_activity '] + $this->sess_expiration) < $this->now)
{
$this->sess_destroy ();
return FALSE;
}
Whether the session data is read according to the user's IP
if ($this->sess_match_ip = = TRUE and $session [' ip_address ']! = $this->ci->input->ip_address ())
{
$this->sess_destroy ();
return FALSE;
}
Whether to match session data according to UA
if ($this->sess_match_useragent = = TRUE and Trim ($session [' user_agent '])! = Trim (substr ($this->ci->input- >user_agent (), 0, 120)))
{
$this->sess_destroy ();
return FALSE;
}
If the session storage, this way should be more secure, of course, when the load is large, it is not recommended that the database read and write pressure is large
if ($this->sess_use_database = = = TRUE)
{
$this->ci->db->where (' session_id ', $session [' session_id ']);
if ($this->sess_match_ip = = TRUE)
{
$this->ci->db->where (' ip_address ', $session [' ip_address ']);
}
if ($this->sess_match_useragent = = TRUE)
{
$this->ci->db->where (' user_agent ', $session [' user_agent ']);
}
$query = $this->ci->db->get ($this->sess_table_name);
No result? Kill it!
if ($query->num_rows () = = 0)
{
$this->sess_destroy ();
return FALSE;
}
Is there custom data? If So, add it to the main session array
$row = $query->row ();
if (Isset ($row->user_data) and $row->user_data! = ")
{
$custom _data = $this->_unserialize ($row->user_data);
if (Is_array ($custom _data))
{
foreach ($custom _data as $key = $val)
{
$session [$key] = $val;
}
}
}
}
Session is valid!
$this->userdata = $session;
Unset ($session);
return TRUE;
}
// --------------------------------------------------------------------
/**
* Writes the read session data to the
*/
function Sess_write ()
{
Whether to write to DB
if ($this->sess_use_database = = = FALSE)
{
$this->_set_cookie ();
Return
}
Set the custom UserData, the session data we'll set in a second
$custom _userdata = $this->userdata;
$cookie _userdata = Array ();
Before continuing, we need to determine if there are any custom data to deal with.
Let's determine the removing the default indexes to see if there ' s anything left in the array
and set the session data while we ' re at it
foreach (Array (' session_id ', ' ip_address ', ' user_agent ', ' last_activity ') as $val)
{
unset ($custom _userdata[$val]);
$cookie _userdata[$val] = $this->userdata[$val];
}
Did we find any custom data? If not, we turn the empty array into a string
Since there ' s no reason to serialize and store a empty array in the DB
if (count ($custom _userdata) = = = 0)
{
$custom _userdata = ";
}
Else
{
Serialize the custom data array so we can store it
$custom _userdata = $this->_serialize ($custom _userdata);
}
Update session Record
$this->ci->db->where (' session_id ', $this->userdata[' session_id ');
$this->ci->db->update ($this->sess_table_name, Array (' last_activity ' = $this->userdata[' Last_ Activity '], ' user_data ' = $custom _userdata));
Write the cookie. Notice that we manually pass the cookie data array to the
_set_cookie () function. Normally that function would store $this->userdata, but
In this case, the array contains custom data, which we don't want in the cookie.
$this->_set_cookie ($cookie _userdata);
}
// --------------------------------------------------------------------
/**
* Create a new session
*/
function Sess_create ()
{
Guaranteed SESSID Safety Only
$sessid = ";
while (strlen ($SESSID) < 32)
{
$sessid. = Mt_rand (0, Mt_getrandmax ());
}
$sessid. = $this->ci->input->ip_address ();
$this->userdata = Array (
' session_id ' = MD5 (Uniqid ($SESSID, TRUE)),
' IP_Address ' = $this->ci->input->ip_address (),
' User_agent ' = substr ($this->ci->input->user_agent (), 0, 120),
' Last_activity ' = $this->now,
' User_data ' and ' = '
);
Save the data to the DB if needed
if ($this->sess_use_database = = = TRUE)
{
$this->ci->db->query ($this->ci->db->insert_string ($this->sess_table_name, $this UserData));
}
Write the cookie
$this->_set_cookie ();
}
// --------------------------------------------------------------------
/**
* Update session
*/
function Sess_update ()
{
Default five-minute update
if (($this->userdata[' last_activity ') + $this->sess_time_to_update) >= $this->now)
{
Return
}
Save the old session ID so we know which record to
Update in the database if we need it
$old _sessid = $this->userdata[' session_id ');
$new _sessid = ";
while (strlen ($new _sessid) < 32)
{
$new _sessid. = Mt_rand (0, Mt_getrandmax ());
}
The session ID even more secure we'll combine it with the user ' s IP
$new _sessid. = $this->ci->input->ip_address ();
Turn it into a hash
$new _SESSID = MD5 (uniqid ($new _sessid, TRUE));
Update the session data in the session data array
$this->userdata[' session_id ') = $new _sessid;
$this->userdata[' last_activity ') = $this->now;
_set_cookie () would handle this for us if we aren ' t using Database sessions
By pushing all userdata to the cookie.
$cookie _data = NULL;
Chance to update the database
if ($this->sess_use_database = = = TRUE)
{
Set cookie explicitly to only has our session data
$cookie _data = Array ();
foreach (Array (' session_id ', ' ip_address ', ' user_agent ', ' last_activity ') as $val)
{
$cookie _data[$val] = $this->userdata[$val];
}
$this->ci->db->query ($this->ci->db->update_string ($this->sess_table_name, Array (' Last_ Activity ' = $this->now, ' session_id ' + $new _sessid), Array (' session_id ' = $old _sessid));
}
Re-write session
$this->_set_cookie ($cookie _data);
}
// --------------------------------------------------------------------
/**
* Destroy all current session data
*/
function Sess_destroy ()
{
Kill the session DB row
if ($this->sess_use_database = = = TRUE && isset ($this->userdata[' session_id '))
{
$this->ci->db->where (' session_id ', $this->userdata[' session_id ');
$this->ci->db->delete ($this->sess_table_name);
}
Kill the cookie
Setcookie (
$this->sess_cookie_name,
Addslashes (serialize (Array ())),
($this->now-31500000),
$this->cookie_path,
$this->cookie_domain,
0
);
Kill Session Data
$this->userdata = Array ();
}
// --------------------------------------------------------------------
/**
* Gets the value of the specified element in the session array
*/
function UserData ($item)
{
Return (! isset ($this->userdata[$item]))? FALSE: $this->userdata[$item];
}
// --------------------------------------------------------------------
/**
* Get all session data
*/
function All_userdata ()
{
return $this->userdata;
}
// --------------------------------------------------------------------
/**
* Add and modify custom session data
*/
function Set_userdata ($newdata = Array (), $newval = ")
{
if (is_string ($newdata))
{
$newdata = Array ($newdata = = $newval);
}
Support Array Combination method
if (count ($newdata) > 0)
{
foreach ($newdata as $key = $val)
{
$this->userdata[$key] = $val;
}
}
$this->sess_write ();
}
// --------------------------------------------------------------------
/**
* Delete the elements in the session array,
*/
function Unset_userdata ($newdata = Array ())
{
if (is_string ($newdata))
{
$newdata = Array ($newdata = =);
}
if (count ($newdata) > 0)
{
foreach ($newdata as $key = $val)
{
unset ($this->userdata[$key]);
}
}
$this->sess_write ();
}
// ------------------------------------------------------------------------
/**
* Add or change flashdata, only available
* Until the next request
*
* @access Public
* @param mixed
* @param string
* @return void
*/
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);
}
}
}
// ------------------------------------------------------------------------
/**
* CI support flash data that is, the session data is only available for the next server request, sometimes if you still want the request after the next request is still valid ...
* Keep_flashdata function is to continue to keep the flash data, make it in the next request also valid
*/
function Keep_flashdata ($key)
{
Mark Flash data as New
$old _flashdata_key = $this->flashdata_key. ': o LD: '. $key;
$value = $this->userdata ($old _flashdata_key);
$new _flashdata_key = $this->flashdata_key. ': New: ' $key;
$this->set_userdata ($new _flashdata_key, $value);
}
// ------------------------------------------------------------------------
/**
* Get Flash data
*/
function Flashdata ($key)
{
$flashdata _key = $this->flashdata_key. ': o LD: '. $key;
return $this->userdata ($flashdata _key);
}
// ------------------------------------------------------------------------
/**
* Mark Flash data as old for _flashdata_sweep to clear the data
*/
function _flashdata_mark ()
{
$userdata = $this->all_userdata ();
foreach ($userdata as $name = $value)
{
$parts = Explode (': New: ', $name);
if (Is_array ($parts) && count ($parts) = = = 2)
{
$new _name = $this->flashdata_key. ': o LD: '. $parts [1];
$this->set_userdata ($new _name, $value);
$this->unset_userdata ($name);
}
}
}
// ------------------------------------------------------------------------
/**
* Flash out data marked as old
*/
function _flashdata_sweep ()
{
$userdata = $this->all_userdata ();
foreach ($userdata as $key = $value)
{
if (Strpos ($key, ': Old: '))
{
$this->unset_userdata ($key);
}
}
}
Get current time
function _get_time ()
{
if (Strtolower ($this->time_reference) = = ' GMT ')
{
$now = time ();
$time = Mktime (Gmdate ("H", $now), Gmdate ("I", $now), Gmdate ("s", $now), Gmdate ("M", $now), Gmdate ("D", $now), Gmdate ("Y", $now));
}
Else
{
$time = time ();
}
return $time;
}
// --------------------------------------------------------------------
/**
* Write Session Cookie
*
*/
function _set_cookie ($cookie _data = NULL)
{
if (Is_null ($cookie _data))
{
$cookie _data = $this->userdata;
}
Serializing arrays
$cookie _data = $this->_serialize ($cookie _data);
Encrypt data
if ($this->sess_encrypt_cookie = = TRUE)
{
$cookie _data = $this->ci->encrypt->encode ($cookie _data);
}
Else
{
If encryption is not used, we provide a MD5 hash to prevent userside tampering
$cookie _data = $cookie _data.md5 ($cookie _data. $this->encryption_key);
}
Sess_expire_on_close is true, the browser is closed and the session expires
$expire = ($this->sess_expire_on_close = = = TRUE)? 0: $this->sess_expiration + time ();
Set the cookie
Setcookie (
$this->sess_cookie_name,
$cookie _data,
$expire,
$this->cookie_path,
$this->cookie_domain,
$this->cookie_secure
);
}
// --------------------------------------------------------------------
/**
* Serialized Array
*/
function _serialize ($data)
{
if (Is_array ($data))
{
foreach ($data as $key = $val)
{
if (is_string ($val))
{
$data [$key] = str_replace (' \ \ ', ' {{slash}} ', $val);
}
}
}
Else
{
if (is_string ($data))
{
$data = str_replace (' \ \ ', ' {{slash}} ', $data);
}
}
Return serialize ($DATA);
}
// --------------------------------------------------------------------
/**
* Deserialization Array
*/
function _unserialize ($data)
{
$data = @unserialize (strip_slashes ($data));
if (Is_array ($data))
{
foreach ($data as $key = $val)
{
if (is_string ($val))
{
$data [$key] = Str_replace (' {{slash}} ', ' \ \ ', $val);
}
}
return $data;
}
Return (is_string ($data))? Str_replace (' {{slash} ', ' \ \ ', $data): $data;
}
// --------------------------------------------------------------------
/**
* Recovery/deletion of invalid session information in database
*/
function _sess_gc ()
{
if ($this->sess_use_database! = TRUE)
{
Return
}
Srand (Time ());
if (rand ()%) < $this->gc_probability)
{
$expire = $this->now-$this->sess_expiration;
$this->ci->db->where ("Last_activity < {$expire}");
$this->ci->db->delete ($this->sess_table_name);
Log_message (' Debug ', ' Session garbage collection performed. ');
}
}
}

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.