m82amjad
m82amjad

Reputation: 248

Codeigniter 3 get a specific session data by id

Codeigniter 3 session table looks like the following

CREATE TABLE IF NOT EXISTS `ci_sessions` (
    `id` varchar(40) NOT NULL,
    `ip_address` varchar(45) NOT NULL,
    `timestamp` int(10) unsigned DEFAULT 0 NOT NULL,
    `data` blob NOT NULL,
    KEY `ci_sessions_timestamp` (`timestamp`)
  );

I can access my current session by

 $this->session

But If I'd like to access a specific session how would I do that.

I can get the session like

    $this->db->where('id', 'db256c0b82f8b6ba1e857d807ea613792817157a');
    $res = $this->db->get('ci_sessions');
    echo $res->row()->data;

I get the following

    __ci_last_regenerate|i:1450694483;email|s:18:"[email protected]";user_code|s:7:"AAA1787";loginInId|i:8;users_id|s:11:"00000000002";active|s:1:"1";username|s:13:"amzadmojumder";fname|s:5:"Amzad";lname|s:8:"Mojumder";phone|s:11:"07900642131";title|s:1:"#";created_on|s:19:"2015-12-17 16:31:56";last_login|s:19:"0000-00-00 00:00:00";in_group|s:15:"2,1,3,4,5,6,7,8";

How could I convert this to an php object or array? I have tried to

 unserialize($res->row()->data);

Also tried

session_decode($res->row()->data);

none of this worked. Any help will be appreciated.

Upvotes: 0

Views: 2524

Answers (3)

Asif Thebepotra
Asif Thebepotra

Reputation: 330

I have solved this problem by creating helper function to update session from existing session id.

Reference : https://forum.codeigniter.com/thread-61330-post-322814.html#pid322814

function updateSession( $session_id='' ) {
        $ci =& get_instance();
        // Kill any current sessions we're in to prevent conflicts
        $ci->session->sess_destroy();
        // Get the Session we want to duplicate
        $ci->db->where( 'id', $session_id );
        $session = $ci->db->get( 'ci_sessions' );
        $row = $session->row();
        if($row){
            $session_db_data = $row->data;
            $session_data = array();  // array where you put your "BLOB" resolved data
            $offset = 0;
            while ($offset < strlen($session_db_data)) 
            {
                if (!strstr(substr($session_db_data, $offset), "|")) 
                {
                    throw new Exception("invalid data, remaining: " . substr($session_db_data, $offset));
                }
                $pos = strpos($session_db_data, "|", $offset);
                $num = $pos - $offset;
                $varname = substr($session_db_data, $offset, $num);
                $offset += $num + 1;
                $data = unserialize(substr($session_db_data, $offset));
                $session_data[$varname] = $data;  
                $offset += strlen(serialize($data));
            }
            $ci->session->set_userdata($session_data);
        }
    }

Upvotes: 0

tegaphilip
tegaphilip

Reputation: 21

Old question, yeah but this worked for me.

https://github.com/wikimedia/php-session-serializer

After fetching the session data from database, I just did

$array = PhpSessionSerializer::decode($session);

Upvotes: 1

Firstly, the CodeIgniter sessions table should look a bit more like this:

CREATE TABLE IF NOT EXISTS  `ci_sessions` (
    session_id varchar(40) DEFAULT '0' NOT NULL,
    ip_address varchar(45) DEFAULT '0' NOT NULL,
    user_agent varchar(120) NOT NULL,
    last_activity int(10) unsigned DEFAULT 0 NOT NULL,
    user_data text NOT NULL,
PRIMARY KEY (session_id),
KEY `last_activity_idx` (`last_activity`)
);

You'll also need to edit your config.php to ensure the following are set properly for CI Sessions to use a table for storage

$config['sess_use_database'] = TRUE;
$config['sess_table_name'] = 'ci_sessions';

The other issue you'll face is that you aren't really using sessions how they're supposed to be used. If you want to mimic sessions of another individual through an admin switch or something like that, you're probably best off creating a new session and duplicating the information in your table. If you actually assume the session, you risk breaking it or letting it expire while another user is accessing it. So I would write your own parsing function to duplicate a specific session in the database, like so:

Your session data is broken up like this in your dB:

__ci_last_regenerate|i:1450694483;
email|s:18:"[email protected]";
user_code|s:7:"AAA1787";
loginInId|i:8;
users_id|s:11:"00000000002";
active|s:1:"1";
username|s:13:"amzadmojumder";
fname|s:5:"Amzad";
lname|s:8:"Mojumder";
phone|s:11:"07900642131";
title|s:1:"#";
created_on|s:19:"2015-12-17 16:31:56";
last_login|s:19:"0000-00-00 00:00:00";
in_group|s:15:"2,1,3,4,5,6,7,8";

The basic architecture is as such:

{session_key}|{information type s=string, i=int}:{length}:"{value}";

So we can grab it from the database and parse through it

<?php

duplicateSession( $id_to_duplicate ) {
    // Kill any current sessions we're in to prevent conflicts
    $this->session->sess_destroy();

    // Get the Session we want to duplicate
    $this->db->where( 'id', $id_to_duplicate );
    $session = $this->db->get( 'ci_sessions' );
    $data = $session->row()->data;

    // Turn our data into an array so we can parse through it
    $data_arr = explode( ';', $data );

    // Loop through each of our items to parse it out
    foreach( $data_arr as $session_key ) {
        // Explode out to separate our key name from our values
        $session_key_arr = explode( '|', $session_key );
        $key_index = $session_key_arr[0];

        // Explode out to parse our values
        $session_value_arr = explode( ':', $session_key_arr[1] );
        $key_value = $session_value_arr[2];

        // Build our new session index
        $this->session->set_userdata( $key_index, $key_value );
    }     
}

?>

Upvotes: 0

Related Questions