CI Framework session.php Source Analysis _php Example

Source: Internet
Author: User
Tags garbage collection md5 md5 hash session id sessions set cookie setcookie strlen

CI is not the session of the original session, it is all of my previous cookie based session, in addition, CI can be selected according to the user configuration will be stored in the database session, I like this function, there is "flash data" function, Both flash out the data only to the next server request can, and then will be 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 '); Set Flash Data

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

$this->session->keep_flashdata (' item '); Keep Flash data

Copy Code code 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 = '; Table name in which the session is saved to data


var $sess _expiration = 7200; Expiration time of Session


var $sess _expire_on_close = FALSE; Whether the session expires automatically when the browser window closes


var $sess _match_ip = false;//Whether to read the session data through the user's IP address


var $sess _match_useragent = TRUE; Whether you want to read the session data according to the corresponding User Agent.


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 the session cookie is updated


var $encryption _key = '; Encryption key


var $flashdata _key = ' flash ';


var $time _reference = ' time ';


var $gc _probability = 5; Ability to recycle session


var $userdata = array (); User session Data Save variable


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 ();


Get configuration data in 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);


}


Must set Encryption_key


if ($this->encryption_key = = ")


{


Show_error (' In-order "use" session class "are 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 no valid time for the session is set, 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 out data of the marked old


$this->_flashdata_sweep ();


Data that marks new flash data as old is flashed out on the next request


$this->_flashdata_mark ();


Reclaim/Delete Expired sessions


$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 the cookie is encrypted


if ($this->sess_encrypt_cookie = = TRUE)


{


$session = $this->ci->encrypt->decode ($session);


}


Else


{


Encryption wasn't 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 is 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 what is expected. This is could be a possible hacking attempt. ');


$this->sess_destroy ();


return FALSE;


}


}


Deserialize a session array that is stored in a cookie


$session = $this->_unserialize ($session);


Detecting data for a session


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 expired?


if ($session [' last_activity '] + $this->sess_expiration) < $this->now)


{


$this->sess_destroy ();


return FALSE;


}


Whether to read session data based on user 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 is in storage, this way should be more secure, of course, when the load is large, it is not recommended, the database read and write pressure


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 this by removing the "default indexes to" if there ' s anything left in the array


and set the session data with 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 is 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 ()


{


Guarantee SESSID Security 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 ' => '


);


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 sessions ID so we know which


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 ());


}


To make 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;


Probability of updating a database


if ($this->sess_use_database = = TRUE)


{


Set cookie explicitly to only have we 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 of 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 supports flash data that means session data is only available for the next server request, and sometimes if you want to make a request after the next request is still valid ...


* Keep_flashdata function is to continue to keep flashing data to make it effective at the next request


*/


function Keep_flashdata ($key)


{


Mark the 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 the flash data as old so that _flashdata_sweep clears 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 the flashing 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 an array of


$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


$cookie _data = $cookie _data.md5 ($cookie _data. $this->encryption_key);


}


Sess_expire_on_close is true, the browser closes, session fails


$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);


}


// --------------------------------------------------------------------


/**


* Deserialize an 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;


}


// --------------------------------------------------------------------


/**


* Reclaim/delete Invalid session information in the 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.