session入库,就是重写session制机,在session的周期内,获得到session的数据并记录到数据库
session默认是存放到服务器上的文件中,不方便管理,如果能把session存放到数据库中就可以方便的对数据库进行管理了
比如:
* 1、可以解决跨域操作
* 2、可以实现单点登录
* 3、可以统计在线人数
* 4、可以踢出在线用户
* 5、可以实现同一时只允许一个用户在线
一、要使用到的知识点
bool session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc )
主要功能:设置session保存形式(文件、mysql、memcache、redis、mongodb)
参数说明:
$open :open函数,主要负责开启session
$close :close函数,主要负责关闭session
$read :session读取(读取MySQL数据)
$write :session写入(写入MySQL数据)
$destroy :销毁指定的session
$gc :1440秒(24分钟),垃圾回收机制,默认1/1000
二、更改session的存储机制
// 定义6个函数,实现更改session的存储机制 // open/close/read/write/destroy/gc function open() { echo __FUNCTION__; echo '<br />'; } function close() { echo __FUNCTION__; echo '<br />'; } function read() { echo __FUNCTION__; echo '<br />'; } function write() { echo __FUNCTION__; echo '<br />'; } function destroy() { echo __FUNCTION__; echo '<br />'; } function gc() { echo __FUNCTION__; echo '<br />'; } // 更改session的存储机制 session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc'); // 开启session session_start(); // 设置session $_SESSION['adminuser'] = 'admin'; // 销毁session session_destroy();
运行结果:
open
read
destroy
close
当我们没有使用session_destroy进行操作时,系统会执行open/read/write/close,如开启,则执行open/read/destroy/close。整个程序中,只有gc垃圾回收机制没有执行,为什么呢?
答:gc属于垃圾回收机制,其不需要每次都执行,其被设定成一定的概率,默认为1/1000,此值可以在php.ini文件中进行设置,参数如下:
我们也可以通过ini_set函数来设置此概率。
// 设置session.gc_divisor参数 ini_set('session.gc_divisor', 1);
三、session入库
(1)设计数据库
create table session ( sess_id char(32) not null, sess_data text, sess_expire int, unique key(sess_id) )charset=utf8;
(2)实现session六步走:open/close/read/write/destroy/gc
/** * 实现open方法,主要负责连接数据库 */ function open() { // 连接数据库 mysql_connect('localhost','root','123'); mysql_query('use test'); mysql_query('set names utf8'); } /** * 实现close方法,主要负责关闭数据库连接 */ function close() { // 关闭数据库连接 mysql_close(); } /** * 实现read方法,主要负责读取session_id的session数据 * @param string $sess_id,读取操作时,系统会自动将当前会话的session_id作为参数传递给$sess_id */ function read($sess_id) { // 获取最大的过期时间 $expire = time() - ini_get('session.gc_maxlifetime'); // 组装sql语句 $sql = "select sess_data from session where sess_id='$sess_id' and sess_expire >= $expire"; // 执行sql语句 $res = mysql_query($sql); // 读取sess_data数据 if ($row = mysql_fetch_assoc($res)) { return $row['sess_data']; } return ''; } /** * 实现write方法,主要负责写入数据到数据库中 * @param string $sess_id,写入操作时,系统会将当前会话的session_id作为参数传递给$sess_id * @param string $sess_data,写入操作时,系统会将当前会话的session数据作为参数传递给$sess_data */ function write($sess_id, $sess_data) { // 定义生成session文件的系统时间 $time = time(); // 组装sql语句 $sql = "replace into session value ('$sess_id', '$sess_data', $time)"; // 执行sql语句 return mysql_query($sql); } /** * 实现destroy方法,主要负责删除指定的session_id数据 * @param string $sess_id,删除操作时,系统会将会话的session_id作为参数传递给$sess_id */ function destroy($sess_id) { // 定义sql语句 $sql = "delete from session where sess_id='$sess_id'"; // 执行sql语句 return mysql_query($sql); } /** * 实现gc方法,主要负责删除过期的session数据 */ function gc() { // 定义过期时间 $expire = time() - ini_get('session.gc_maxlifetime'); // 定义sql语句 $sql = "delete from session where sess_expire < $expire"; // 执行sql语句 return mysql_query($sql); }
(3)计算过期时间
生成session文件的时间(sess_expire) + 1440 >= time()(当前时间)
生成session文件的时间(sess_expire)>= time() – 1440
(4)更改session的存储机制
// 更改session的存储机制 session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc'); // 开启session session_start(); // 设置session $_SESSION['adminuser'] = 'admin'; echo $_SESSION['adminuser'];
运行结果: