session使用分布式Redis无效的最终解决方案(3.2.3)

浏览:2705 发布日期:2016/10/06 分类:技术分享 关键字: session Redis
经过了一段时间的研究,终于解决了将session保存到redis中的问题。
我不清楚这是官方的BUG,还是程序就是这么设计的。
在TP的session方法中,只有传入参数是数组的时候,才会去执行session_set_save_handler,如果使用session('name','value')的方法,便不执行session_set_save_handler,程序自然无效。
下面我给改写了一下,直接覆盖到/ThinkPHP/Common/functions.php文件的同名方法即可。function session($name='',$value='') {
    $prefix   =  C('SESSION_PREFIX');
    if(C('SESSION_TYPE')) { // 读取session驱动
        $type   = C('SESSION_TYPE');
        $class  = strpos($type,'\\')? $type : 'Think\\Session\\Driver\\'. ucwords(strtolower($type));
        $hander = new $class();
        session_set_save_handler(
            array(&$hander,"open"), 
            array(&$hander,"close"), 
            array(&$hander,"read"), 
            array(&$hander,"write"), 
            array(&$hander,"destroy"), 
            array(&$hander,"gc")
        );
        // 启动session
        if(C('SESSION_AUTO_START'))  session_start();
    }
    if(is_array($name)) { // session初始化 在session_start 之前调用
        if(isset($name['prefix'])) C('SESSION_PREFIX',$name['prefix']);
        if(C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])){
            session_id($_REQUEST[C('VAR_SESSION_ID')]);
        }elseif(isset($name['id'])) {
            session_id($name['id']);
        }
        if('common' == APP_MODE){ // 其它模式可能不支持
            ini_set('session.auto_start', 0);
        }
        if(isset($name['name']))            session_name($name['name']);
        if(isset($name['path']))            session_save_path($name['path']);
        if(isset($name['domain']))          ini_set('session.cookie_domain', $name['domain']);
        if(isset($name['expire']))          {
            ini_set('session.gc_maxlifetime',   $name['expire']);
            ini_set('session.cookie_lifetime',  $name['expire']);
        }
        if(isset($name['use_trans_sid']))   ini_set('session.use_trans_sid', $name['use_trans_sid']?1:0);
        if(isset($name['use_cookies']))     ini_set('session.use_cookies', $name['use_cookies']?1:0);
        if(isset($name['cache_limiter']))   session_cache_limiter($name['cache_limiter']);
        if(isset($name['cache_expire']))    session_cache_expire($name['cache_expire']);
        if(isset($name['type']))            C('SESSION_TYPE',$name['type']);
    }elseif('' === $value){ 
        if(''===$name){
            // 获取全部的session
            return $prefix ? $_SESSION[$prefix] : $_SESSION;
        }elseif(0===strpos($name,'[')) { // session 操作
            if('[pause]'==$name){ // 暂停session
                session_write_close();
            }elseif('[start]'==$name){ // 启动session
                session_start();
            }elseif('[destroy]'==$name){ // 销毁session
                $_SESSION =  array();
                session_unset();
                session_destroy();
            }elseif('[regenerate]'==$name){ // 重新生成id
                session_regenerate_id();
            }
        }elseif(0===strpos($name,'?')){ // 检查session
            $name   =  substr($name,1);
            if(strpos($name,'.')){ // 支持数组
                list($name1,$name2) =   explode('.',$name);
                return $prefix?isset($_SESSION[$prefix][$name1][$name2]):isset($_SESSION[$name1][$name2]);
            }else{
                return $prefix?isset($_SESSION[$prefix][$name]):isset($_SESSION[$name]);
            }
        }elseif(is_null($name)){ // 清空session
            if($prefix) {
                unset($_SESSION[$prefix]);
            }else{
                $_SESSION = array();
            }
        }elseif($prefix){ // 获取session
            if(strpos($name,'.')){
                list($name1,$name2) =   explode('.',$name);
                return isset($_SESSION[$prefix][$name1][$name2])?$_SESSION[$prefix][$name1][$name2]:null;  
            }else{
                return isset($_SESSION[$prefix][$name])?$_SESSION[$prefix][$name]:null;                
            }            
        }else{
            if(strpos($name,'.')){
                list($name1,$name2) =   explode('.',$name);
                return isset($_SESSION[$name1][$name2])?$_SESSION[$name1][$name2]:null;  
            }else{
                return isset($_SESSION[$name])?$_SESSION[$name]:null;
            }            
        }
    }elseif(is_null($value)){ // 删除session
        if(strpos($name,'.')){
            list($name1,$name2) =   explode('.',$name);
            if($prefix){
                unset($_SESSION[$prefix][$name1][$name2]);
            }else{
                unset($_SESSION[$name1][$name2]);
            }
        }else{
            if($prefix){
                unset($_SESSION[$prefix][$name]);
            }else{
                unset($_SESSION[$name]);
            }
        }
    }else{ // 设置session
        if(strpos($name,'.')){
            list($name1,$name2) =   explode('.',$name);
            if($prefix){
                $_SESSION[$prefix][$name1][$name2]   =  $value;
            }else{
                $_SESSION[$name1][$name2]  =  $value;
            }
        }else{
            if($prefix){
                $_SESSION[$prefix][$name]   =  $value;
            }else{
                $_SESSION[$name]  =  $value;
            }
        }
    }
    return null;
}
redis操作类,依然使用了sd2536888大神的redis操作类:
http://www.thinkphp.cn/extend/547.html

但我做了一个小修改,把session数据放到了session分支下,使用Redis管理软件比较方便管理,否则都在根目录太过烦乱。

附件 Redis.class.rar ( 2.37 KB 下载:68 次 )

最佳答案
评论( 相关
后面还有条评论,点击查看>>