thinkphp3.2.3 使用redis session存储
为了解决session 共享问题,使用redis存储session会话信息
首先我们先研究一下 thinkphp 底层是怎么调用session的
ThinkPHP/Library/Think/App.class.php 有这么一段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /** * 运行应用实例 入口文件使用的快捷方法 * @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的处理器,所以说要定义一下
1 | SESSION_OPTIONS 这个配置 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | /** * 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | <?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 Think\Session\Driver; use think\Exception; 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了,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /* 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 , 最后测试一下
1 2 3 4 5 6 7 | public function test() { session_start(); echo session_id(); session( 'userid' ,123); //设置session dump(session()); die ; } |
最后效果如下:
备注,session 有一些配置,比如是不是强制使用cookie
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步