php 改变 sesseion_save_handler,PHP session_set_save_handler():将Session存储到数据库

通过前面的学习我们知道,Session 是存储在服务器的临时目录中的,当站点的登陆人数较多时,也就意味着服务器中会存储大量的 Session 文件,很占服务器资源。而服务器想要在这众多的 Session 中查找指定的 Session_id 也并不是什么轻松的事情。出现这种情况时该怎么办呢?这时我们可以选择将 Session 存储到数据库中,以减轻服务器的压力。

PHP 中的 session_set_save_handler() 函数可以设置自定义的会话存储函数,通过这些自定义函数来操作 Session,从而将 Session 信息存储到数据库中。session_set_save_handler() 函数有两种形式,其语法格式如下:

session_set_save_handler(

callable $open,

callable $close,

callable $read,

callable $write,

callable $destroy,

callable $gc

[, callable $create_sid

[, callable $validate_sid

[, callable $update_timestamp]]]

)

参数说明如下:

$open(string $savePath, string $sessionName):$open 回调函数类似于类的构造函数,在会话打开的时候会被自动调用。这是自动开始会话或者通过调用 session_start() 手动开始会话之后第一个被调用的回调函数。此回调函数操作成功会返回 TRUE,反之返回 FALSE;

$close():$close 回调函数类似于类的析构函数。 在 $write 回调函数调用之后调用。当调用 session_write_close() 函数之后,也会调用 $close 回调函数。此回调函数操作成功返回 TRUE,反之返回 FALSE;

$read(string $sessionId):如果会话中有数据的话,$read 回调函数会返回 $sessionId 所对应的 Session 数据;如果会话中没有数据,那么 $read 回调函数会返回空字符串。在会话自动开始或者通过调用 session_start() 函数手动开始会话之后,PHP 会在内部调用 $read 回调函数来获取会话数据。在调用 $read 之前,PHP 会调用 $open 回调函数;

$write(string $sessionId, string $data):在创建或修改 Session 信息时会调用 $write 回调函数。此回调函数接收当前会话的 ID 以及 $_SESSION 中数据序列化之后的字符串作为参数。序列化会话数据是由 PHP 根据 session.serialize_handler 设定值来自动完成;

$destroy($sessionId):当调用 session_destroy() 函数或者调用 session_regenerate_id() 函数并且设置 $destroy 参数为 TRUE 时,会调用此回调函数。此回调函数操作成功返回 TRUE,反之返回 FALSE;

$gc($lifetime):为了清理会话中的旧数据,PHP 会不时的调用垃圾收集回调函数。调用周期由 session.gc_probability 和 session.gc_divisor 参数控制。传入到此回调函数的 $lifetime 参数由 session.gc_maxlifetime 设置。此回调函数操作成功返回 TRUE,反之返回 FALSE;

$create_sid():可选参数,当需要新的会话 ID 时被调用的回调函数。回调函数被调用时不用传入参数,其返回值应该是一个字符串格式的、有效的会话 ID;

$validate_sid():可选参数,用来验证会话 ID;

$update_timestamp():可选参数,用来修改时间戳。

除了上面这种形式,session_set_save_handler() 函数还有另外一种形式(自 PHP5.4 及以上版本可用),如下所示:

session_set_save_handler(object $sessionhandler [, bool $register_shutdown = TRUE])

参数说明如下:

$sessionhandler:实现了 SessionHandlerInterface、SessionIdInterface 或 SessionUpdateTimestampHandlerInterface 接口的对象,例如 SessionHandler;

$register_shutdown:可选参数,将函数 session_write_close() 注册为 register_shutdown_function() 函数。

一般函数的参数都是直接使用变量,但是 session_set_save_handler() 函数中却是以多个函数的名称作为参数。下面将通过示例的形式对这几个参数(函数)分别进行讲解。

1) 封装 sess_open() 函数,用来连接数据库,示例代码如下:

// 连接数据库

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() 函数,用来关闭数据库连接,示例代码如下:

// 关闭数据库连接

function sess_close(){

global $link;

mysqli_close($link);

return true;

}

?>

在这个函数中不需要任何参数,所以不论是将 Session 存储到数据库还是文件中,都只需返回 true 即可。但是这里是将 Session 存储到数据库中,所以最好还是在这里将数据库关闭,以避免出现其它问题。

3) 封装 sess_read() 函数,根据参数 $sessionId 来获取 Session 的信息,示例代码如下:

// 读取 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 内容写入数据库,示例代码如下:

// 写入 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 数据,示例代码如下:

// 删除 Session

function sess_destroy($sessionId){

global $link;

$sql = "DELETE FROM session WHERE id = '$sessionId'";

return mysqli_query($link, $sql);

}

?>

6) 封装 sess_gc() 函数,用来清理失效的 Session,示例代码如下:

// 清理失效的 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 存储到数据库中,示例代码如下:

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 信息写入到数据库,如下所示:

mysql> SELECT * FROM session;

+--------------------------------+-------------------+--------------+

| id                                             | data                     | lapse_time    |

+--------------------------------+-------------------+--------------+

| c91mct86sfs3gs9lpke225b8ir | user|s:5:"admin";  | 1595587392 |

+--------------------------------+-------------------+--------------+

1 row in set (0.00 sec)

上面代码中 ini_set("session.save_handler", "user"); 用来临时修改 PHP 的配置信息,与直接将 php.ini 配置文件中 session.save_handler 的值改为 user 效果相同。另外需要注意的是,以上代码仅在 PHP7.0 版本中成功运行,其它版本暂未测试通过。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值