• thinkphp3.2.3 使用redis session存储


    为了解决session 共享问题,使用redis存储session会话信息

    首先我们先研究一下 thinkphp 底层是怎么调用session的

    ThinkPHP/Library/Think/App.class.php  有这么一段

       /**
         * 运行应用实例 入口文件使用的快捷方法
         * @access public
         * @return void
         */
        static public function run() {
            // 应用初始化标签
            Hook::listen('app_init');
            App::init();
            // 应用开始标签
            Hook::listen('app_begin');
            // Session初始化
            if(!IS_CLI){
                session(C('SESSION_OPTIONS'));
            }
            // 记录应用初始化时间
            G('initTime');
            App::exec();
            // 应用结束标签
            Hook::listen('app_end');
            return ;
        }
    

    如果不是cli模式,则初始化 session, 找到  ThinkPHP/Common/functions.php 的session函数,如果是数组,则初始化session的处理器,所以说要定义一下 

    SESSION_OPTIONS  这个配置
    /**
     * session管理函数
     * @param string|array $name session名称 如果为数组则表示进行session设置
     * @param mixed $value session值
     * @return mixed
     */
    function session($name='',$value='') {
        $prefix   =  C('SESSION_PREFIX');
        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']);
            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();
        }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,那么则需要加装一个 驱动文件,默认tp3.2.3  是没有的

    下面的文件放到这个路径下:ThinkPHP/Library/Think/Session/Driver/Redis.class.php

    <?php
    // +----------------------------------------------------------------------
    // | ThinkPHP [ WE CAN DO IT JUST THINK ]
    // +----------------------------------------------------------------------
    // | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
    // +----------------------------------------------------------------------
    // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
    // +----------------------------------------------------------------------
    // | Author: liu21st <liu21st@gmail.com>
    // +----------------------------------------------------------------------
    namespace ThinkSessionDriver;
    
    use thinkException;
    
    class Redis implements SessionHandlerInterface
    {
        /** @var Redis */
        protected $handler = null;
        protected $config = [
            // redis主机
            'host' => '127.0.0.1',
            // redis端口
            'port' => 6379,
            // 密码
            'password' => 123456',
            // 操作库
            'select' => 1,
            // 有效期(秒)
            'expire' => 3600,
            // 超时时间(秒)
            'timeout' => 0,
            // 是否长连接
            'persistent' => true,
            // sessionkey前缀
            'session_name' => 'session_',
        ];
    
        public function __construct($config = [])
        {
            $this->config['host'] = C("SESSION_REDIS_HOST") ? C("SESSION_REDIS_HOST") : $this->config['host'];
            $this->config['port'] = C("SESSION_REDIS_POST") ? C("SESSION_REDIS_POST") : $this->config['port'];
            $this->config['password'] = C("SESSION_REDIS_AUTH") ? C("SESSION_REDIS_AUTH") : $this->config['password'];
            $this->config['select'] = C("SESSION_REDIS_SELECT") ? C("SESSION_REDIS_SELECT") : $this->config['select'];
            $this->config['expire'] = C("SESSION_REDIS_EXPIRE") ? C("SESSION_REDIS_EXPIRE") : $this->config['expire'];
            $this->config['session_name'] = C('SESSION_PREFIX') ? C('SESSION_PREFIX') : $this->config['session_name'];
            $this->config['timeout'] = C('SESSION_CACHE_TIMEOUT') ? C('SESSION_CACHE_TIMEOUT') : $this->config['timeout'];
    
        }
    
        /**
         * 打开Session
         * @access public
         * @param string $savePath
         * @param mixed $sessName
         * @return bool
         * @throws Exception
         */
        public function open($savePath, $sessName)
        {
            // 检测php环境
            if (!extension_loaded('redis')) {
                throw new Exception('not support:redis');
            }
            $this->handler = new Redis;
            // 建立连接
            $func = $this->config['persistent'] ? 'pconnect' : 'connect';
            $this->handler->$func($this->config['host'], $this->config['port'], $this->config['timeout']);
            if ('' != $this->config['password']) {
                $this->handler->auth($this->config['password']);
            }
            if (0 != $this->config['select']) {
                $this->handler->select($this->config['select']);
            }
            return true;
        }
    
        /**
         * 关闭Session
         * @access public
         */
        public function close()
        {
            $this->gc(ini_get('session.gc_maxlifetime'));
            $this->handler->close();
            $this->handler = null;
            return true;
        }
    
        /**
         * 读取Session
         * @access public
         * @param string $sessID
         * @return string
         */
        public function read($sessID)
        {
            return (string)$this->handler->get($this->config['session_name'] . $sessID);
        }
    
        /**
         * 写入Session
         * @access public
         * @param string $sessID
         * @param String $sessData
         * @return bool
         */
        public function write($sessID, $sessData)
        {
    
            if ($this->config['expire'] > 0) {
                return $this->handler->setex($this->config['session_name'] . $sessID, $this->config['expire'], $sessData);
            } else {
                return $this->handler->set($this->config['session_name'] . $sessID, $sessData);
            }
        }
    
        /**
         * 删除Session
         * @access public
         * @param string $sessID
         * @return bool
         */
        public function destroy($sessID)
        {
            return $this->handler->delete($this->config['session_name'] . $sessID) > 0;
        }
    
        /**
         * Session 垃圾回收
         * @access public
         * @param string $sessMaxLifeTime
         * @return bool
         */
        public function gc($sessMaxLifeTime)
        {
            return true;
        }
    }
    

      

    那么配置一下就OK了,

    /* SESSION设置 begin*/
        //初始化 session 配置数组 支持type name id path expire domain 等参数
        'SESSION_OPTIONS'       =>  array(
            'type'=>'Redis',
            'prefix'=>'sess_',
            'path'=>'tcp://127.0.0.1:6379?auth=123456',
            'expire'=>3600,
        ),
    
        'SESSION_AUTO_START'    =>  true,    // 是否自动开启Session
        'SESSION_TYPE'          =>  'Redis', // session hander类型 默认无需设置 除非扩展了session hander驱动
        'SESSION_PREFIX'        =>  'sess_', // session 前缀
        'VAR_SESSION_ID'        =>  'session_id', //sessionID的提交变量
    
        //begin
        'SESSION_PERSISTENT'    =>  1,//是否长连接(对于php来说0和1都一样)
        'SESSION_CACHE_TIMEOUT' =>  3,//连接超时时间(秒)
        'SESSION_REDIS_EXPIRE'  =>  3600,        //session有效期(单位:秒) 0表示永久缓存
        'SESSION_REDIS_HOST'    =>  '127.0.0.1', //redis服务器ip
        'SESSION_REDIS_PORT'    =>  '6379',       //端口
        'SESSION_REDIS_AUTH'    =>  '123456', //认证密码
        'SESSION_REDIS_SELECT'  =>  '1',  //操作库
        //end
        /* SESSION设置 end*/
    

      

    随便找个controller , 最后测试一下

    public function test()
    {
        session_start();
        echo session_id();
        session('userid',123);  //设置session
        dump(session());die;
    }

    最后效果如下:

    备注,session 有一些配置,比如是不是强制使用cookie

    https://www.cnblogs.com/okzzx/p/7006912.html

  • 相关阅读:
    eclipse快捷键失效
    git学习 branch log rebase merge fetch remote add push pull
    解决netty tcp自定义消息格式粘包/拆包问题
    多线程while(!state){}有问题,volatile优化,sleep睡着之后唤醒,刷新变量缓存
    玄学eclipse ,突然所有文件报错,然后,ctrl+a, ctrl+x, ctrl+v就好了
    玄学springboot applicationcontext.getBean(用类名String还是类型Class), getBean(..)的调用场景结果不同?getBean(..)还会阻塞?@DependsOn按照名称依赖,那么getBean用类名String
    玄学yml,被@ActiveProfiles注解误导
    玄学yml,被@ActiveProfiles注解误导
    java动态代理,多服务实例,线程安全target,注解,面向切面修改具有注解的方法行为,ThreadLocal<Object>
    java键盘输入方法-
  • 原文地址:https://www.cnblogs.com/lixiuran/p/12174906.html
Copyright © 2020-2023  润新知