前言
session的默认存储器是文件形式,每新建一个会话,都会在我们磁盘中产生一个新会话的文件。
如果说我们的网站用户是千万级的,每个用户在登录的时候都会产生一个会话文件,那我们的磁盘中是不是有千万级的会话文件.当用户第二次再来访问时,查询指定的session_id,需要在这个千万个文件中来查找这一个,那这个速度会是很慢的.所以说默认基于文件的形式存储它的性能不是很好,这时候我们就要考虑使用我们自定义的方式来存储session数据
- 数据库形式使用mysql作为会话管理器,因为需要用到数据库进行查询,会影响性能。(不推荐)(当然可以考虑在数据库前面加一台缓存服务器)
- 最佳方法:使用memcache或redis作为会话管理器最佳。
实现原理:PHP实现预留SessionHandlerInterface接口从而将session存储到数据库中
DROP TABLE IF EXISTS `session`;
CREATE TABLE `session` (
`session_id` char(40) NOT NULL,
`session_data` varchar(200) NOT NULL DEFAULT '',
`session_expires` int(11) NOT NULL DEFAULT '0',
`session_create_time` int(11) NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
<?php
//已mysql为例上代码
class CustomSession implements SessionHandlerInterface
{
private $link; //连接地址
private $lifetime; //指定过了多少秒之后数据就会被清除 默认1440s(24分)
public function open($savepath,$session_name)
{
$this->lifetime = get_cfg_var('session.gc_maxlifetime');
$this->link = mysqli_connect('localhost','root','root');
mysqli_set_charset($this->link,'utf8');
mysqli_select_db($this->link,'test');
if($this->link){
return true;
}else{
return false;
}
}
public function close()
{
mysqli_close($this->link);
return true;
}
public function read($session_id)
{
$session_id = mysqli_escape_string($this->link,$session_id);
$sql = "SELECT * FROM session WHERE session_id = '{$session_id}' AND session_expires>".time();
$result = mysqli_query($this->link,$sql);
if(mysqli_num_rows($result)==1){
return serialize(mysqli_fetch_assoc($result));
}else{
return '';
}
}
public function write($session_id ,$session_data )
{
$newExp = time()+$this->lifetime;
$time = time();
$session_id = mysqli_escape_string($this->link,$session_id);
//首先查询是否存在指定的session_id .如果存在则更新数据库,不存在则写入数据
$sql = "SELECT * FROM session WHERE session_id = '{$session_id}' ";
$result = mysqli_query($this->link,$sql);
if(mysqli_num_rows($result) ==1){
$sql = "UPDATE session SET session_expires = '{$newExp}' ,session_data = '{$session_data}' WHERE session_id = '{$session_id}'";
}else{
$sql = "INSERT session VALUES ('{$session_id}', '{$session_data}' , '{$newExp}' , '{$time}')";
}
//echo $sql;
mysqli_query($this->link,$sql);
return mysqli_affected_rows($this->link)==1;
}
public function destroy($sesion_id)
{
$session_id = mysqli_escape_string($session_id);
$sql = "DELETE FROM session WHERE session_id = '{$session_id}' ";
mysqli_query($this->link,$sql);
return mysqli_affected_rows($this->link)==1;
}
public function gc($maxlifetime)
{
$sql = "DELETE FROM session WHERE session_expires<".time();
mysqli_query($this->link,$sql);
if(mysqli_affected_rows($this->link)>0){
return true;
}else{
return false;
}
}
}
调用
<?php
require_once "CustomSession.php";
$CustomSession = new CustomSession;
//ini_set('session.save_handler','user');
session_set_save_handler($CustomSession,true);
session_start();
$_SESSION ['username'] = '康彦霖';
$_SESSION ['email'] = '774774989@qq.com';