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 ...
随机推荐
- python基础-异常(exception)处理
python基础-异常(exception)处理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 程序中难免出现错误,而错误分成两种,即语法错误和逻辑错误.语法错误根本过不了pyth ...
- wav文件格式及ffmpeg处理命令
wav文件头详解 符合RIFF(Resource Interchange File Format)规范的wav文件的文件头记录了音频流的编码参数等基本信息.wav文件由多个块组成,至少包含RIFF标志 ...
- 手把手教你使用webpack搭建vue框架
我们在使用vue开发项目的时候,都是用vue-cli直接来搭建的.但是这是别人已经造好的轮子,我们既然要使用别人造好的轮子,我们总不能知其然而不知其所以然.所以呢,我这边文章就教你如何使用webpac ...
- C#_连接数据库实现 登录注册界面
//编写登录界面逻辑 using System; using System.Collections.Generic; using System.ComponentModel; using System ...
- 从github上下载一个csv文件
when u open the raw file(i.e. csv) on github, then point to RAW button, then right click the mouse, ...
- 《区块链100问》第84集:资产代币化之对标黄金Digix
黄金是避险的不二选择.Digix发行的黄金代币则是数字资产世界里的黄金,其代币简称DGX,能够在数字资产世界中起到避险的作用. DGX如何实现对标黄金呢?它将黄金资产进行了上链(即:区块链)操作.举个 ...
- Strusts2笔记7--国际化
国际化: 国际化是指,使程序在不做任何修改的情况下,就可以使用在不同的语言环境中.国际化在一般性项目中是不常用的.在编程中简称 i18n. 国际化是通过读取资源文件的形式实现的.资源文件的定义与注册, ...
- 解决java计算中double类型结果不一致问题,使用BigDecimal解决
一.需求:从数据表中读出一个double的数据,比如是3.5,没问题,但是如果再用3.5进行计算,比如乘以100,结果就是350了,而是35000000004 因为是浮点运算,所有语言中的浮点数都会有 ...
- 1->小规模集群架构规划
"配置无人值守批量安装系统(Cobbler)" "搭建PPTP VPN/ NTP/Firewalld内部共享上网 " "搭建跳板机服务jumpserv ...
- 一文看懂python主要应用领域或应用场景
Python简介 Python(英国发音:/ˈpaɪθən/美国发音:/ˈpaɪθɑːn/),是一种面向对象的解释型计算机程序设计语言,由荷兰人GuidovanRossum于1989年发明,第一个公开 ...