【问题标题】:Losing session data in code igniter在 codeigniter 中丢失会话数据
【发布时间】:2016-04-22 09:24:46
【问题描述】:

我遇到了会话数据问题。登录网站后,我丢失了会话数据。我已经厌倦了在数据库中创建会话,也尝试了原生 php 会话类,但没有任何效果。我还从服务器中清除了 tmp 文件夹。 该网站使用code igniter框架,托管在godaddy VPS上 请帮我。谢谢...

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

class CI_Session {
    var $session_id_ttl; // session id time to live (TTL) in seconds
   var $flash_key = 'flash'; // prefix for "flash" variables (eg. flash:new:message)



function CI_Session()
{
    $this->object =& get_instance();
    log_message('debug', "Native_session Class Initialized");
    $this->_sess_run();
}

/**
* Regenerates session id
*/
function regenerate_id()
{
    // copy old session data, including its id
    $old_session_id = session_id();
    $old_session_data = $_SESSION;

    // regenerate session id and store it
    session_regenerate_id();
    $new_session_id = session_id();

    // switch to the old session and destroy its storage
    session_id($old_session_id);
    session_destroy();

    // switch back to the new session id and send the cookie
    session_id($new_session_id);
    session_start();

    // restore the old session data into the new session
    $_SESSION = $old_session_data;

    // update the session creation time
    $_SESSION['regenerated'] = time();

    // session_write_close() patch based on this thread
    // http://www.codeigniter.com/forums/viewthread/1624/
    // there is a question mark ?? as to side affects

    // end the current session and store session data.
    session_write_close();
}

/**
* Destroys the session and erases session storage
*/
function destroy()
{
    //unset($_SESSION);
    session_unset();
    if ( isset( $_COOKIE[session_name()] ) )
    {
          setcookie(session_name(), '', time()-42000, '/');
    }
    session_destroy();
}

/**
* Reads given session attribute value
*/    
function userdata($item)
{
    if($item == 'session_id'){ //added for backward-compatibility
        return session_id();
    }else{
        return ( ! isset($_SESSION[$item])) ? false : $_SESSION[$item];
    }
}

/**
* Sets session attributes to the given values
*/
function set_userdata($newdata = array(), $newval = '')
{
    if (is_string($newdata))
    {
        $newdata = array($newdata => $newval);
    }

    if (count($newdata) > 0)
    {
        foreach ($newdata as $key => $val)
        {
            $_SESSION[$key] = $val;
        }
    }
}

/**
* Erases given session attributes
*/
function unset_userdata($newdata = array())
{
    if (is_string($newdata))
    {
        $newdata = array($newdata => '');
    }

    if (count($newdata) > 0)
    {
        foreach ($newdata as $key => $val)
        {
            unset($_SESSION[$key]);
        }
    }        
}

/**
* Starts up the session system for current request
*/
function _sess_run()
{

    $session_id_ttl = $this->object->config->item('sess_expiration');

    if (is_numeric($session_id_ttl))
    {
        if ($session_id_ttl > 0)
        {
            $this->session_id_ttl = $this->object->config->item('sess_expiration');
        }
        else
        {
            $this->session_id_ttl = (60*60*24*365*2);
        }
    }

    session_start();

    // check if session id needs regeneration
    if ( $this->_session_id_expired() )
    {
        // regenerate session id (session data stays the
        // same, but old session storage is destroyed)
        $this->regenerate_id();
    }

    // delete old flashdata (from last request)
    //$this->_flashdata_sweep();

    // mark all new flashdata as old (data will be deleted before next request)
    //$this->_flashdata_mark();
}

/**
* Checks if session has expired
*/
function _session_id_expired()
{   
    if ( !isset( $_SESSION['regenerated'] ) )
    {
        $_SESSION['regenerated'] = time();
        return false;
    }

    $expiry_time = time() - $this->session_id_ttl;

    if ( $_SESSION['regenerated'] <=  $expiry_time )
    {
        return true;
    }

    return false;
}

/**
* Sets "flash" data which will be available only in next request (then it will
* be deleted from session). You can use it to implement "Save succeeded" messages
* after redirect.
*/
function set_flashdata($key, $value)
{
    $flash_key = $this->flash_key.':new:'.$key;
    $this->set_userdata($flash_key, $value);
}

/**
* Keeps existing "flash" data available to next request.
*/
function keep_flashdata($key)
{
    $old_flash_key = $this->flash_key.':old:'.$key;
    $value = $this->userdata($old_flash_key);

    $new_flash_key = $this->flash_key.':new:'.$key;
    $this->set_userdata($new_flash_key, $value);
}

/**
* Returns "flash" data for the given key.
*/
function flashdata($key)
{
    $flash_key = $this->flash_key.':old:'.$key;
    return $this->userdata($flash_key);
}

/**
* PRIVATE: Internal method - marks "flash" session attributes as 'old'
*/
function _flashdata_mark()
{
    foreach ($_SESSION as $name => $value)
    {
        $parts = explode(':new:', $name);
        if (is_array($parts) && count($parts) == 2)
        {
            $new_name = $this->flash_key.':old:'.$parts[1];
            $this->set_userdata($new_name, $value);
            $this->unset_userdata($name);
        }
    }
}

/**
* PRIVATE: Internal method - removes "flash" session marked as 'old'
*/
function _flashdata_sweep()
{
    foreach ($_SESSION as $name => $value)
    {
        $parts = explode(':old:', $name);
        if (is_array($parts) && count($parts) == 2 && $parts[0] == $this->flash_key)
        {
            $this->unset_userdata($name);
        }
    }
}
}

【问题讨论】:

  • $this->session->userdata 的转储结果是什么?
  • 第一个转储包含插入的数据。但是页面重定向后的第二个转储只包含会话ID,而不是前一个(会话ID自动更改)
  • 你能在这里发布你的生成会话代码吗?你使用 $this->session->set_userdata() 吗?
  • 在_session_id_expired函数中,if条件总是为真,即$_SESSION['regenereated']中没有数据
  • 为什么不使用 codeigniter 本身的会话库?

标签: php codeigniter session


【解决方案1】:

总是喜欢根据框架的格式创建会话。即使我也有同样的问题。当时我使用的是 codeigniter 2.0 版,所以我使用了框架会话定义。但据我所知 $_SESSION 全局变量在 version 3 中受支持

添加自定义会话数据

$this->session->userdata('item');
$this->session->set_userdata($array);

检索会话数据

$this->session->userdata('item');

检索所有会话数据

$this->session->all_userdata()

删除会话数据

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

查看此文档,您可以获得清晰的视图 https://ellislab.com/codeigniter/user-guide/libraries/sessions.html

【讨论】:

  • Array ([session_id] => 5788ffe0d0b78f2b7cd7c8b948cdca9f [ip_address] => 'my_ip_address' [user_agent] => Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0. 2623.112 Safari/537.36 [last_activity] => 1461318458 [user_data] => [usertype] => 'some_date'[username] => 'some_data' [utype] => 'some_data' )
  • 现在我正在使用默认框架会话。检查页面重定向前和页面重定向后的两个结果。
  • Array ([session_id] => 22d66f3d73121c6aee2e856cf92a2f65 [ip_address] => 'my_ip_address' [user_agent] => Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0. 2623.112 Safari/537.36 [last_activity] => 1461318503 [user_data] => )
  • 告诉我每次重新加载页面时是否调用函数regenerate_id()
  • 没有。 if ( $this->_session_id_expired() ) 总是失败,所以函数 regenerate_id() 永远不会调用
【解决方案2】:

当有任何页面重定向时,在重定向代码后保持“退出”。 这就是我解决问题的方法(页面重定向后丢失会话数据)。请参见下面的示例。

header("Location: example.php");
exit;

【讨论】:

    猜你喜欢
    • 2013-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 2012-12-16
    • 1970-01-01
    • 2013-01-06
    • 2017-05-03
    相关资源
    最近更新 更多