当前位置:首页 > 技术文章 > WEB开发 > PHP

解决CI框架CI_Session与PHP默认Session不能共享的问题

发布时间:2017-12-12 18:22:47 作者:superl 来源:superl\'s blog 点击量:

作者:superl

来源:http://www.superl.org/post-Codeigniter_session.html

 

Codeigniter是一个很不错的PHP的框架,笔者也很喜欢使用。但是在CI的SESSION类有很多人吐槽!


最近需要为一个已经上线的网站开发一个辅助的客服系统,辅助的系统需要判断主系统的用户是否登录,也就是判断$_SESSION['userid']之类的。也使用了CI进行开发,但是现实很残酷,发现CI根本获取不到采用PHP默认SESSION方式存储的$_SESSION['userid']的值! 因为CI的SESSION类是重写了的,有点蛋疼。


使用总结:

    在CI框架的控制器里面使用$_SESSION['userid']=1,只要是CI框架的控制器,都可以打印出来。

    在外部写一个独立的test.php文件,使用$_SESSION['userid']=1,在CI框架的内部控制器就读取不到。


为了实现Codeigniter的SESSION与PHP默认SESSION的共享,总结出有下面2个方法,强烈推荐第二种:


方法一:不使用CI的SESSION库

 

 

 

只要不在autoload.php里面初始化载入ci的session库,以及不在控制器里面动态载入,那么CI就使用的是默认的SESSION方式。

但是这个方法有点难搞,毕竟要是外部主系统是别人开发的,很多地方都动态载入了session库,那么就要删除很多地方,甚至引发兼容问题

 

方法二:改写CI的SESSION库 【推荐】【亲测通过】


通过改写CI的SESSION库,就可以获取到默认的session了。

在github上面找到了一个大牛自己改写的Session Library, 核心就是弃用cookie,转而使用php native session, 保留了一些基本功能,比如 set_userdata()。但是在测试中发现,会出现几个warring和notice级别的错误提示,笔者进行了细微的调整改进,下面共享出来测试无误的Session.php文件。

 

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

/**
 * Code Igniter
 *
 * An open source application development framework for PHP 4.3.2 or newer
 *
 * @package        Codeigniter
 * @author        Dariusz Debowczyk
 * @copyright    Copyright (c) 2006, D.Debowczyk
 * @license        http://www.codeignitor.com/user_guide/license.html
 * @link        http://www.Codeigniter.com
 * @since        Version 1.0
 * @filesource
 */

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

/**
 * Session class using native PHP session features and hardened against session fixation.
 *
 * @package        Codeigniter
 * @subpackage    Libraries
 * @category    Sessions
 * @author        Dariusz Debowczyk
 * @link        http://www.Codeigniter.com/user_guide/libraries/sessions.html
 */
class CI_session {
    var $session_id_ttl = 360; // session id time to live (TTL) in seconds
    var $flash_key = 'flash'; // prefix for "flash" variables (eg. flash:new:message)

    function CI_session()
    {
        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 = NULL)
    {
        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_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);
            }
        }
    }
}

第一步:把/system/libraries/Session/目录下的Session.php文件重命名为Session_old.php

 

第二步:保存上面的代码为Session.php文件,保存到CI框架的/system/libraries/Session/目录下

本文链接:http://www.topjishu.net/article/74.html,如有转载,请注明出处!


关键词:CI框架,CI_Session,Session,共享


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表