Codeigniter 3通过id获取特定的会话数据

时间:2015-12-21 12:04:29

标签: codeigniter-3

Codeigniter 3会话表如下所示

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

我可以通过

访问我当前的会话
 $this->session

但如果我想访问特定的会话,我该怎么做呢。

我可以像

那样得到会话
    $this->db->where('id', 'db256c0b82f8b6ba1e857d807ea613792817157a');
    $res = $this->db->get('ci_sessions');
    echo $res->row()->data;

我得到以下

    __ci_last_regenerate|i:1450694483;email|s:18:"amzadfof@gmail.com";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";

我怎么能将它转换为php对象或数组?我试过

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

也试过

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

这一切都没有奏效。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:0)

首先,CodeIgniter会话表看起来应该更像这样:

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

您还需要编辑config.php以确保为CI会话正确设置以下内容以使用表进行存储

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

你将面临的另一个问题是你并没有真正使用会话如何使用它们。如果你想通过管理员开关或类似的东西模仿另一个人的会话,你可能最好创建一个新会话并复制表中的信息。如果您实际上假设会话,则在另一个用户访问它时,您可能会破坏它或让它过期。所以我会编写你自己的解析函数来复制数据库中的特定会话,如下所示:

你的会话数据在你的dB中分解如下:

__ci_last_regenerate|i:1450694483;
email|s:18:"amzadfof@gmail.com";
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";

基本架构是这样的:

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

所以我们可以从数据库中获取它并通过它解析

<?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 );
    }     
}

?>

答案 1 :(得分:0)

老问题,是的,但这对我有用。

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

从数据库中获取会话数据后,我就做了

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

答案 2 :(得分:0)

我已经通过创建帮助程序功能来解决此问题,该功能可以从现有会话ID更新会话。

参考: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);
        }
    }