Welcome Guest, Not a member yet? Register   Sign In
Cannot unserialize ci_sessions from database
#1

I try to create realtime monitoring user using session database.
I've can unserialize ci_sessions in codeigniter 2.x.x, but in Codeigniter 3.x.x I can't. After I use var_dump there is defferent format, like this

This is from codeigniter 2.x.x
Code:
string(174) "a:5:{s:9:"user_data";s:0:"";s:12:"namapengguna";s:21:"[email protected]";s:8:"platform";s:11:"Windows 8.1";s:7:"browser";s:20:"Chrome 41.0.2272.118";s:9:"logged_in";b:1;}"

This is from codeigniter 3.x.x
Code:
string(186) "__ci_last_regenerate|i:1428652689;idpengguna|s:0:"";idgrup|s:0:"";namapengguna|s:21:"[email protected]";platform|s:11:"Windows 8.1";browser|s:20:"Chrome 41.0.2272.118";logged_in|b:1;"

I think in codeigniter doesn't have "{" "}" in column data.

This is my error code
Code:
A PHP Error was encountered

Severity: Notice

Message: unserialize(): Error at offset 0 of 186 bytes

Filename: rmonitoring/Data.php

Line Number: 37

Backtrace:

File: D:\htdocs\ci_for_basic\application\models\rmonitoring\Data.php
Line: 37
Function: unserialize

File: D:\htdocs\ci_for_basic\application\controllers\Rmonitoring.php
Line: 37
Function: get_data_monitoring

File: D:\htdocs\ci_for_basic\index.php
Line: 292
Function: require_once

and This is my PHP Code
PHP Code:
$data = array(
 
           'id',
 
           'ip_address',
 
           'timestamp',
 
           'data'
 
       );
 
       $this->db->select($data);
 
       $query $this->db->get("ci_sessions");
 
       foreach ($query->result() as $row)
 
         
            $res 
$row->data;
 
           $udata unserialize($res);
 
           if(!empty($udata['namapengguna'])){
 
               echo $row->ip_address;
 
               echo $udata['namapengguna'];
 
               echo date("d-m-Y H:i:s",$row->timestamp);
 
               echo $udata['browser'];
 
               echo $udata['platform'];
 
           }
 
       

So what's wrong i my code ? Can you help me ?   Sad
Reply
#2

(This post was last modified: 04-10-2015, 03:53 AM by InsiteFX.)

In CI 3.0 it doe's not look like they are using the unserialize and serialize methods anymore.

Best to look at the session class to see what's going on.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#3

(04-10-2015, 03:45 AM)InsiteFX Wrote: In CI 3.0 it doe's not look like they are using the unserialize and serialize methods anymore.

Best to look at the session class to see what's going on.

I try to looking CI_Session_database_driver.php, and I found Serialized session data
But I still don't understand  Sad
I've poor skill of PHP

PHP Code:
/**
     * Read
     *
     * Reads session data and acquires a lock
     *
     * @param    string    $session_id    Session ID
     * @return    string    Serialized session data
     */
    
public function read($session_id)
    {
        if (
$this->_get_lock($session_id) !== FALSE)
        {
            
// Needed by write() to detect session_regenerate_id() calls
            
$this->_session_id $session_id;

            
$this->_db
                
->select('data')
                ->
from($this->_config['save_path'])
                ->
where('id'$session_id);

            if (
$this->_config['match_ip'])
            {
                
$this->_db->where('ip_address'$_SERVER['REMOTE_ADDR']);
            }

            if ((
$result $this->_db->get()->row()) === NULL)
            {
                
$this->_fingerprint md5('');
                return 
'';
            }

            
// PostgreSQL's variant of a BLOB datatype is Bytea, which is a
            // PITA to work with, so we use base64-encoded data in a TEXT
            // field instead.
            
$result = ($this->_platform === 'postgre')
                ? 
base64_decode(rtrim($result->data))
                : 
$result->data;

            
$this->_fingerprint md5($result);
            
$this->_row_exists TRUE;
            return 
$result;
        }

        
$this->_fingerprint md5('');
        return 
'';
    }

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

    /**
     * Write
     *
     * Writes (create / update) session data
     *
     * @param    string    $session_id    Session ID
     * @param    string    $session_data    Serialized session data
     * @return    bool
     */
    
public function write($session_id$session_data)
    {
        
// Was the ID regenerated?
        
if ($session_id !== $this->_session_id)
        {
            if ( ! 
$this->_release_lock() OR ! $this->_get_lock($session_id))
            {
                return 
FALSE;
            }

            
$this->_row_exists FALSE;
            
$this->_session_id $session_id;
        }
        elseif (
$this->_lock === FALSE)
        {
            return 
FALSE;
        }

        if (
$this->_row_exists === FALSE)
        {
            
$insert_data = array(
                
'id' => $session_id,
                
'ip_address' => $_SERVER['REMOTE_ADDR'],
                
'timestamp' => time(),
                
'data' => ($this->_platform === 'postgre' base64_encode($session_data) : $session_data)
            );

            if (
$this->_db->insert($this->_config['save_path'], $insert_data))
            {
                
$this->_fingerprint md5($session_data);
                return 
$this->_row_exists TRUE;
            }

            return 
FALSE;
        }

        
$this->_db->where('id'$session_id);
        if (
$this->_config['match_ip'])
        {
            
$this->_db->where('ip_address'$_SERVER['REMOTE_ADDR']);
        }

        
$update_data = array('timestamp' => time());
        if (
$this->_fingerprint !== md5($session_data))
        {
            
$update_data['data'] = ($this->_platform === 'postgre')
                ? 
base64_encode($session_data)
                : 
$session_data;
        }

        if (
$this->_db->update($this->_config['save_path'], $update_data))
        {
            
$this->_fingerprint md5($session_data);
            return 
TRUE;
        }

        return 
FALSE;
    }

    
// ------------------------------------------------------------------------ 
Reply
#4
Rainbow 

My problem solved, I've use session_decode method
I've read from
http://php.net/manual/en/function.sessio...cation=ufi

And I my code program :
PHP Code:
$data = array(
 
           'id',
 
           'ip_address',
 
           'timestamp',
 
           'data'
 
       );
 
       $this->db->select($data);
 
       $query $this->db->get("ci_sessions");
 
       foreach ($query->result() as $row)
 
         
            $session_data 
$row->data;
 
           
            $return_data 
= array();
 
           $offset 0;
 
           while ($offset strlen($session_data)) {
 
               if (!strstr(substr($session_data$offset), "|")) {
 
                   throw new Exception("invalid data, remaining: " substr($session_data$offset));
 
               }
 
               $pos strpos($session_data"|"$offset);
 
               $num $pos $offset;
 
               $varname substr($session_data$offset$num);
 
               $offset += $num 1;
 
               $data unserialize(substr($session_data$offset));
 
               $return_data[$varname] = $data;
 
               $offset += strlen(serialize($data));
 
           }
 
           
            if
(!empty($return_data['namapengguna'])){
 
               echo date("d-m-Y H:i:s",$row->timestamp);
 
               echo $return_data['namapengguna'];
 
               echo $row->ip_address;
 
               echo $return_data['browser'];
 
               echo $return_data['platform'];
 
           }
 
       
Image result in attachment
Thanks for your help  Big Grin

Attached Files Thumbnail(s)
   
Regards



[email protected]
Application developer
Reply
#5

(04-11-2015, 05:08 AM)pudyastoadi Wrote: My problem solved, I've use session_decode method
I've read from
http://php.net/manual/en/function.sessio...cation=ufi

And I my code program :
PHP Code:
$data = array(
 
           'id',
 
           'ip_address',
 
           'timestamp',
 
           'data'
 
       );
 
       $this->db->select($data);
 
       $query $this->db->get("ci_sessions");
 
       foreach ($query->result() as $row)
 
         
            $session_data 
$row->data;
 
           
            $return_data 
= array();
 
           $offset 0;
 
           while ($offset strlen($session_data)) {
 
               if (!strstr(substr($session_data$offset), "|")) {
 
                   throw new Exception("invalid data, remaining: " substr($session_data$offset));
 
               }
 
               $pos strpos($session_data"|"$offset);
 
               $num $pos $offset;
 
               $varname substr($session_data$offset$num);
 
               $offset += $num 1;
 
               $data unserialize(substr($session_data$offset));
 
               $return_data[$varname] = $data;
 
               $offset += strlen(serialize($data));
 
           }
 
           
            if
(!empty($return_data['namapengguna'])){
 
               echo date("d-m-Y H:i:s",$row->timestamp);
 
               echo $return_data['namapengguna'];
 
               echo $row->ip_address;
 
               echo $return_data['browser'];
 
               echo $return_data['platform'];
 
           }
 
       
Image result in attachment
Thanks for your help  Big Grin
Above code also help me.
Thanks for your help  Big Grin
Reply
#6

I tried your example, but you get all the users!
My question is: is there a way to list only the active users (the users who are online) and exclude the expired sessions.
Thanks.
Reply
#7

For that you would need to keep track of all the users online in a online_users table.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#8

Another potential reason:

You can sometimes come across this issue if you are using different versions of PHP, or if you change the version of PHP you are using while a session was open.


For example if you have a session cookie with an app that uses PHP 5.6.* and then you try to use it with an app (that resides on another sub-domain) that uses PHP 7.2.*, then you are going to get a warning error. Or, if you had an open session and then you changed the version of PHP that you are using with your app (say if you are developing locally and switching around PHP versions), then you'll get the warning. So best to use serialize/unserialize and with PHP version that does not change.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB