使用sae kvdb实现自定义session存储2014.05.30 17:29
默认php将session存储在文件中,但也提供session_set_save_handler函数,可以实现session的自定义存储、读、写、回收、自定义失效时间、统计在线人数等。例如:为了应付大流量,将session存储到内存表、APC、memcache或者redis中。Sea kvdb是一种kv型数据库,所以如果将session存储到memcache/redis,也可以参照此方法设计。
session_set_save_handler函数原型:
1 | bool session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc ) |
操作session时,对应的预先调用$open方法,$read对应读取,$write对应写写入,$destroy会在调用session_destroy时执行,并且php会不定时的调用$gc回收过期session(回收概率由php.ini中session.gc_probability ,session.gc_divisor商来决定,默认为1%)。
为了方便控制session的定时失效,在kvdb中存储时,除了记录sessionid对应的session值,还要记录该sessionid对应的失效时间戳。
Kvdb中key的定义:
1 2 | Session_data:sessionid string Session_expire:sessionid int(unix时间戳,方便与当前时间比对,确定session是否已失效) |
实现:
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 | class HttpSession { private static $kv ; private static $lifeTime ; public static function start() { session_set_save_handler( array ( __CLASS__ , 'open' ), array ( __CLASS__ , 'close' ), array ( __CLASS__ , 'read' ), array ( __CLASS__ , 'write' ), array ( __CLASS__ , 'destroy' ), array ( __CLASS__ , 'gc' )); session_start(); } public static function open( $savePath , $sessionName ) { self:: $kv = new SaeKV(); self:: $kv ->init(); self:: $lifeTime =get_cfg_var( 'session.gc_maxlifetime' ); return true; } public static function close() { return true; } /** * 根据当前时间,返回未过期的session值 */ public static function read( $sid ) { if ( $time =self:: $kv ->get( 'session_expire:' . $sid )) if ( $time >time()) return self:: $kv ->get( 'session_data:' . $sid ); return '' ; } /** * 记录session值以及对应的过期时间戳,如果已经存在sessionid,则更新时间戳 */ public static function write( $sid , $sdata ) { return self:: $kv ->set( 'session_data:' . $sid , $sdata ) && self:: $kv ->set( 'session_expire:' . $sid , time()+self:: $lifeTime ); } public static function destroy( $sid ) { return self:: $kv -> delete ( 'session_data:' . $sid ) && self:: $kv -> delete ( 'session_expire:' . $sid ); } /** * 遍历kv中session_expire,删除失效session */ public static function gc( $maxLifeTime ) { $ret = self:: $kv ->pkrget( 'session_expire:' , 1); while (true) { $start_key = key( $ret ); $i = count ( $ret ); if ( $i < 1) break ; if ( array_pop ( $ret )<time()) { self:: $kv -> delete ( $start_key ); $sid =ltrim( $start_key , 'session_expire:' ); self:: $kv -> delete ( 'session_data:' . $sid ); echo 'session_data:' . $sid ; } $ret = self:: $kv ->pkrget( 'session_expire:' , 1, $start_key ); } return true; } } |
使用:
1 2 3 4 | HttpSession::start(); $_SESSION [ 'bb' ]= 'bbbb' ; $_SESSION [ 'cc' ]= 'cccc' ; Var_dump( $_SESSION ); |
通过遍历kvdb中数据就能看到,生成的对应两条session记录
1 2 3 4 | Array( [session_data:8c276998ab68a9255f1c7eea0c8c00ed] => bb|s:4: "bbbb" ;cc|s:4: "cccc" ; [session_expire:8c276998ab68a9255f1c7eea0c8c00ed] => 1401526458 ) |
在操作session时,如果session_expire:sessionid小于当前时间,证实该session已经失效,$_SESSION会对应返回一个空array,并且kvdb中session_data:sessionid也会自动更新为空。
相关文章
<< 上一篇 ibframework - 一个简介轻量级的PHP开发框架 新域名上线啦! 下一篇 >>
- 正在加载用户留言,请稍后~