通过前面的学习我们知道,Session 是存储在服务器的临时目录中的,当站点的登陆人数较多时,也就意味着服务器中会存储大量的 Session 文件,很占服务器资源。而服务器想要在这众多的 Session 中查找指定的 Session_id 也并不是什么轻松的事情。出现这种情况时该怎么办呢?这时我们可以选择将 Session 存储到数据库中,以减轻服务器的压力。
PHP 中的 session_set_save_handler() 函数可以设置自定义的会话存储函数,通过这些自定义函数来操作 Session,从而将 Session 信息存储到数据库中。session_set_save_handler() 函数有两种形式,其语法格式如下:
参数说明如下:
除了上面这种形式,session_set_save_handler() 函数还有另外一种形式(自 PHP5.4 及以上版本可用),如下所示:
参数说明如下:
一般函数的参数都是直接使用变量,但是 session_set_save_handler() 函数中却是以多个函数的名称作为参数。下面将通过示例的形式对这几个参数(函数)分别进行讲解。
1) 封装 sess_open() 函数,用来连接数据库,示例代码如下:
<?php
// 连接数据库
function sess_open($savePath, $sessionName){
global $link;
$link = mysqli_connect('localhost', 'root', 'root') or die('数据库连接失败!');
mysqli_select_db($link, 'testdb') or die('未找到该数据库!');
return true;
}
?>
函数中并没有用到 $save_path 和 $session_name 这两个参数,可以将它们去掉,但是建议读者保留这两个参数,因为一般使用时都是存在这两个变量的,应该养成一个好的习惯。
2) 封装 sess_close() 函数,用来关闭数据库连接,示例代码如下:
<?php
// 关闭数据库连接
function sess_close(){
global $link;
mysqli_close($link);
return true;
}
?>
在这个函数中不需要任何参数,所以不论是将 Session 存储到数据库还是文件中,都只需返回 true 即可。但是这里是将 Session 存储到数据库中,所以最好还是在这里将数据库关闭,以避免出现其它问题。
3) 封装 sess_read() 函数,根据参数 $sessionId 来获取 Session 的信息,示例代码如下:
<?php
// 读取 Session 内容
function sess_read($sessionId){
global $link;
$time = time();
$sql = "SELECT data FROM session WHERE id = '$sessionId' AND lapse_time > '$time'";
$result = mysqli_query($link, $sql);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
if($row){
return $row['data'];
}else{
return false;
}
}
?>
4) 封装 sess_write() 函数,用来将 Session 内容写入数据库,示例代码如下:
<?php
// 写入 Session
function sess_write($sessionId, $data){
global $link;
$lapse_time = time()+(60*60);
$sql = "SELECT data FROM session WHERE id = '$sessionId'";
$result = mysqli_query($link, $sql);
if(mysqli_num_rows($result) == 0){
$ins_sql = "INSERT INTO session VALUES('$sessionId', '$data', '$lapse_time')";
$res = mysqli_query($link, $ins_sql);
}else{
$up_sql = "UPDATE session SET data = '$data', lapse_time = '$lapse_time' WHERE id = '$sessionId'";
$res = mysqli_query($link, $up_sql);
}
return $res;
}
?>
5) 封装 sess_destroy() 函数,用来删除指定的 Session 数据,示例代码如下:
<?php
// 删除 Session
function sess_destroy($sessionId){
global $link;
$sql = "DELETE FROM session WHERE id = '$sessionId'";
return mysqli_query($link, $sql);
}
?>
6) 封装 sess_gc() 函数,用来清理失效的 Session,示例代码如下:
<?php
// 清理失效的 Session
function sess_gc(){
global $link;
$time = time();
$sql = "DELETE FROM session WHERE lapse_time < '$time'";
$res = mysqli_query($link, $sql);
return $res;
}
?>
以上定义的 6 个函数便是 session_set_save_handler() 函数 6 个必选参数,调用 session_set_save_handler() 函数即可实现将 Session 存储到数据库中,示例代码如下:
<?php
ini_set("session.save_handler", "user");
session_set_save_handler('sess_open', 'sess_close', 'sess_read', 'sess_write', 'sess_destroy', 'sess_gc');
session_start();
$_SESSION['user'] = 'admin';
?>
运行上面的代码即可将 user = 'admin' 的 Session 信息写入到数据库,如下所示:
上面代码中 ini_set("session.save_handler", "user"); 用来临时修改 PHP 的配置信息,与直接将 php.ini 配置文件中 session.save_handler 的值改为 user 效果相同。另外需要注意的是,以上代码仅在 PHP7.0 版本中成功运行,其它版本暂未测试通过。