PHP session 写入数据库中的方法
首先解释下为什么要把session 写到数据库中呢,session 一般默认是以文件的形式放在php.ini 配置的目录中的, 如果你的网站实现了多台服务器负载均衡,这样用户访问你的网站,可能进入的服务器就不同,如果没有实现吧session 文件在服务器上实现同步,那么就可能会出现session 丢失问题,最常见的例子就是,我登陆了后台,点着点着 就又让重新登录了,这是个典型的session 没有同步而引起的session 丢失的问题。
解决方案当然有很多,现在介绍一个就是把用户的session 写入到数据库中去,这样session 都从数据库中读取,就不会有丢失的情况发生。
首先要更改php.ini 里面
session.save_handler = files
为:
session.save_handler = user
PHP 有个session_set_save_handler() 函数 ,这个函数就是自定义处理session 的机制,一般 要定义
'open', 'close', 'read', 'write','destroy', 'gc'
这几个函数
下面是个session 写入数据库的一个类
<?php
class SessionToDB
{
private $_path = null;
private $_name = null;
private $_pdo = null;
private $_ip = null;
private $_maxLifeTime = 0; public function __construct(PDO $pdo)
{
//注册处理session 的函数
session_set_save_handler(
array(&$this, 'open'),
array(&$this, 'close'),
array(&$this, 'read'),
array(&$this, 'write'),
array(&$this, 'destroy'),
array(&$this, 'gc')
); $this->_pdo = $pdo;
$this->_ip = !empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null;
$this->_maxLifeTime = ini_get('session.gc_maxlifetime');
} public function open($path,$name)
{
return true;
} public function close()
{
return true;
}
//读取函数
public function read($id)
{
$sql = 'SELECT * FROM session where PHPSESSID = ?';
$stmt = $this->_pdo->prepare($sql);
$stmt->execute(array($id)); if (!$result = $stmt->fetch(PDO::FETCH_ASSOC)) {
return null;
} elseif ($this->_ip != $result['client_ip']) {
return null;
} elseif ($result['update_time']+$this->_maxLifeTime < time()){
$this->destroy($id);
return null;
} else {
return $result['data'];
}
}
//写入函数
public function write($id,$data)
{
$sql = 'SELECT * FROM session where PHPSESSID = ?';
$stmt = $this->_pdo->prepare($sql);
$stmt->execute(array($id)); if ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
if ($result['data'] != $data) {
$sql = 'UPDATE session SET update_time =? , data = ? WHERE PHPSESSID = ?'; $stmt = $this->_pdo->prepare($sql);
$stmt->execute(array(time(), $data, $id));
}
} else {
if (!empty($data)) {
$sql = 'INSERT INTO session (PHPSESSID, update_time, client_ip, data) VALUES (?,?,?,?)';
$stmt = $this->_pdo->prepare($sql);
$stmt->execute(array($id, time(), $this->_ip, $data));
}
}
return true;
}
//销毁函数
public function destroy($id)
{
$sql = 'DELETE FROM session WHERE PHPSESSID = ?';
$stmt = $this->_pdo->prepare($sql);
$stmt->execute(array($id));
return true;
}
//这个函数执行的几率有php.ini 控制
public function gc($maxLifeTime)
{
$sql = 'DELETE FROM session WHERE update_time < ?';
$stmt = $this->_pdo->prepare($sql);
$stmt->execute(array(time() - $maxLifeTime));
return true;
}
}
//调用方式
ini_set('session.save_handler','user');//更改为user 方式
ini_set('session.gc_maxlifetime', '86400');//session 最大有效期可以不设
$dbname='数据库名称';
$dbuser='用户名';
$dbpwd=密码'';
$dbhost='主机地址';
try{
$pdo = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser,$dbpwd);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); new SessionToDB($pdo);
session_start();
} catch(PDOException $e) {
echo 'Error: '.$e->getMessage();
}
?>
数据库结构:
CREATE TABLE `session` (
`PHPSESSID` varchar(50) NOT NULL,
`update_time` int(10) NOT NULL,
`client_ip` varchar(25) NOT NULL,
`data` text NOT NULL,
PRIMARY KEY (`PHPSESSID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
当然解决这个问题的方法很多,思路就是把session 放到服务器 共用的地方.
PHP session 写入数据库中的方法的更多相关文章
- 将Session写入数据库
使用session_set_save_handler()函数,将Session的内容写入数据库 <?php /* *@author Fahy *@link http://home.cnblogs ...
- DataTable数据批量写入数据库三种方法比较
DataTable数据批量写入数据库三种方法比较 标签: it 分类: C#1) insert循环插入:2) sqldataadapter.update(dataset,tablename); ...
- DataTable 数据批量写入数据库三种方法比较
DataTable数据批量写入数据库三种方法比较 1) insert循环插入: 2) sqldataadapter.update(dataset,tablename); 3) sqlbul ...
- C#将图片存放到SQL SERVER数据库中的方法
本文实例讲述了C#将图片存放到SQL SERVER数据库中的方法.分享给大家供大家参考.具体如下: 第一步: ? 1 2 3 4 5 6 7 8 9 10 //获取当前选择的图片 this.pictu ...
- 已知数据库中存在表tb_book2,通过在图书信息界面填写书本的基本信息,然后提交后写入数据库中的表格中。需要对提交的信息进行修改,信息填入不能为空,为空则则有提示。
jsp结合SQLSERVER向数据库中的表添加图书信息. 已知数据库中存在表tb_book2,通过在图书信息界面填写书本的基本信息,然后提交后写入数据库中的表格中.需要对提交的信息进行修改,信息填入不 ...
- 怎样借助log4j把日志写入数据库中
log4j是一个优秀的开源日志记录项目.我们不仅能够对输出的日志的格式自定义,还能够自定义日志输出的目的地,比方:屏幕.文本文件,数据 库,甚至能通过socket输出.本节使用MySQ ...
- 【繁星Code】如何在EF将实体注释写入数据库中
最近在项目中需要把各个字段的释义写到数据库中,该项目已经上线很长时间了,数据库中的字段没有上千也有上百个,要是一个项目一个项目打开然后再去找对应字段查看什么意思,估计要到明年过年了.由于项目中使用En ...
- SQL语句:把Excel文件中数据导入SQL数据库中的方法
1.从Excel文件中,导入数据到SQL数据库情况一.如果接受数据导入的表不存在 select * into jd$ from OPENROWSET('MICROSOFT.JET.OLEDB.4.0' ...
- dede 忘记密码在数据库中修改方法
如何找回或修改dedecms后台管理员登录密码呢? 一个客户把密码忘了,找了很长一会没几个靠谱的回答,dede是使用md5加密,但是,它是显示32位md5加密码从第6位开始的20位 方法是直接修改其m ...
随机推荐
- Kubernetes init container
目录 简介 配置 init container与应用容器的区别 简介 在很多应用场景中,应用在启动之前都需要进行如下初始化操作: 等待其他关联组件正确运行(例如数据库或某个后台服务) 基于环境变量或配 ...
- Hadoop生态圈-hive优化手段-作业和查询优化
Hadoop生态圈-hive优化手段-作业和查询优化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- Vuex深入理解
store下的index.js: import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) let store = new Vuex.St ...
- bzoj千题计划156:bzoj1571: [Usaco2009 Open]滑雪课Ski
http://www.lydsy.com/JudgeOnline/problem.php?id=1571 DP不一定全部全状态转移 贪心的舍去一些不合法的反而更容易转移 在一定能力范围内,肯定滑雪所需 ...
- bzoj千题计划139:bzoj2229: [Zjoi2011]最小割
http://www.lydsy.com/JudgeOnline/problem.php?id=2229 最小割树介绍:http://blog.csdn.net/jyxjyx27/article/de ...
- 鸟哥的书——ubuntu命令
纯粹按着鸟哥的书上的基本命令打一遍,不喜勿喷! Chapter5.首次登录 一.基础命令: 1.显示时间和日期的命令:date dzhwen@deng:~$ date 2014年 02月 23日 星期 ...
- kafka入门(3)- SpringBoot集成Kafka
1.引入依赖 <dependency> <groupId>org.springframework.kafka</groupId> <artifactId> ...
- caffe设计网络教程(一)
假设现在我们要设计一个基于VGG的网络,主要考虑的问题是可否修改VGG类似于resnet那样,应该怎么修改?更具体来说,我们需要在VGG网络上考虑eltwise层,现在我们有三种方案,如下: 方案一: ...
- 【Linux 命令】iftop安装与简单使用
iftop是linux下的一个流量监控工具,用于查看实时网络流量,反向解析IP,显示端口信息官网:http://www.ex-parrot.com/~pdw/iftop/ 1.安装必须软件包 yum ...
- 【leetcode 简单】 第一百四十六题 最长和谐子序列
和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是1. 现在,给定一个整数数组,你需要在所有可能的子序列中找到最长的和谐子序列的长度. 示例 1: 输入: [1,3,2,2,5,2,3,7] ...