php将sessionid存入mysql_将 Session 数据存入数据库

PHP的session会话是将用户信息存储在服务器上。一般情况下,一个sessionId会存储在客户端的Cookie中,然后通过SessionId 去维护session的声明周期的建立和保持。

可是如果客户端的SessionId一旦被其他程序劫持,那么就可以随便访问我们的应用程序了,且我们知道session默认情况是是保存在服务器的某一个目录的文件中,且在分布式上也是不能共享的,

因此我们考虑是否将session可以保存到数据库或缓存数据库中?

答案:当然是可以的,但并不一定是一个最优的方法,比如说数据访问特别大,是不是放在数据库中,给后台数据库带来了很大的压力。这个需要根据自己的场景来选择!

1、自定义Session接口函数session_set_save_hanlder

下面我来看下 php 是如何把session保存在数据库端的。session_set_save_handler(

'custom_session_open',

'custom_session_close',

'custom_session_read',

'custom_session_write',

'custom_session_destroy',

'custom_session_gc'

);

PHP提供了这样的一个函数,重新设置  session 保存的对象。

第一个回调函数open($path,$sessionId) 方法有两个参数。一个是保存的路径,一个是sessionId。

第二个回调函数close()

第三个回调函数read($sessionId)

第四个回调函数write($sessionId,$data)

第五个回调函数destroy($sessionId)

第六个回调函数gc($lifetime)

定时清理,这个时间和php.ini 设置的 session.gc_maxlifetime 有关系

2、数据库表设计create table session(

sessionid varchar(128) primary key,

content mediumblob,

createtime int(14),

ip int(10) DEFAULT 0,

key(createtime,sessionid)

);

content为什么使用 mediublob 类型? 因为会话数据库既有字符串也可能有二进制数据,正是因为此原因,在数据库中使用Blob二进制类型的字符,这样不仅保障数据的安全,而且占用的存储空间也会变少。

我们在设计表时,使用了一个复合键,如果数据特别多的时候,可以使用进行优化,这里就不做优化了。

就执行上边的表结构 创建session表。

3、SessionDbSaveHandler类  命名为SessionDbSaveHandler.phpclass SessionDbSaveHandler {

public $host;

public $user;

public $password;

public $database;

public $table = 'session';

/**

* @var PDO

*/

public static $db;

public function __construct($host, $user, $password, $database, $table = '') {

$this->host = $host;

$this->user = $user;

$this->password = $password;

$this->database = $database;

$table && $this->table = $table;

//自动注册session 保存到数据库

session_set_save_handler(

[$this, 'open'],

[$this, 'close'],

[$this, 'read'],

[$this, 'write'],

[$this, 'destroy'],

[$this, 'gc']

);

$this->connection();

}

private function connection() {

if (!static::$db) {

$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->database;

$params = [

PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION

];

static::$db = new PDO($dsn, $this->user, $this->password, $params);

}

}

/**

* 打开session

* @param $path

* @param $id

*/

public function open($path, $id) {

}

/**

* 关闭session

*/

public function close() {

static::$db = null;

}

/**

* 读取session

* @param $id

* @return string

*/

public function read($id) {

$sql = 'select * from session where sessionid=?';

$statement = self::$db->prepare($sql);

$statement->execute([$id]);

$data = $statement->fetch(PDO::FETCH_OBJ);

return $data ? $data->content : '';

}

/**

* 保存session 或更新session

* @param $id

* @param $data

* @return int

*/

public function write($id, $data) {

$sql = 'replace into session(`sessionid`,`content`,`ip`,`createtime`)values(?,?,?,?)';

$statement = self::$db->prepare($sql);

$result = $statement->execute([$id, $data, $this->ip2long(), time()]);

if ($result) {

return $statement->rowCount();

}

}

/**

* @param $id

* @return int

*/

public function destroy($id) {

$sql = 'delete from session where sessionid=?';

$statement = self::$db->prepare($sql);

$statement->execute([$id]);

return $statement->rowCount();

}

/**

* 定期自动回收

* @param $lifetime

* @return int

*/

public function gc($lifetime) {

$sql = 'delete from session where createtime';

$statement = self::$db->prepare($sql);

$statement->execute([time() - $lifetime]);

return $statement->rowCount();

}

public function __destruct() {

$this->host = null;

$this->user = null;

$this->password = null;

$this->database = null;

session_write_close();

}

private function ip2long($ip = null) {

return sprintf('%u', is_null($ip) ? $_SERVER['REMOTE_ADDR'] : $ip);

}

}

4、测试数据是否正常 写入 读出

写入session:require 'SessionDbSaveHandler.php';

new SessionDbSaveHandler('localhost', 'root', 'song', 'test', 'session');

session_start();

$_SESSION['user'] = '15675736645666';

$_SESSION['random_num'] = mt_rand(1000, 9999);

echo '写入成功';

4f90c2166d56b98ebe7e1bef8ae35738.png

一定要先注册session_set_save_handler 这个函数,

然后再 session_start()  否则数据不能写入到数据库

读取数据:require 'SessionDbSaveHandler.php';

new SessionDbSaveHandler('localhost', 'root', 'song', 'test', 'session');

session_start();

print_r($_SESSION);

eaa6442b6ac24b5f3dfba243af790d0f.png

查看数据库中是否存在:

7563b1ee2d9bd87ed1e5a2af5d21730e.png

数据库表结构:

bcdf94926726e9fd17ff74c695cddd4b.png

如果需要扩展memcache 或  redis  按照这个结构 直接修改里面的代码 即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值