php实现session入库
为什么要把session存入数据库?有什么用?
可以:统计在线人数,现实多站点session共享(通行证),控制同个账号登入人数等。
要实现session的入库,有关键的几个基本知识:
session.gc_divisor = 100 session.gc_probability = 1 。session.gc_probability 与 session.gc_divisor 合起来用来管理 gc(garbage collection 垃圾回收)进程启动的概率。( session.gc_probability/session.gc_divisor = 概率)
session.gc_maxlifetime = 1024 。session.gc_maxlifetime 指定过了多少秒之后数据就会被视为“垃圾”并被清除。
session.save_handler = files 。session.save_handler 定义了来存储和获取与会话关联的数据的处理器的名字。默认为 files。参见 session_set_save_handler()。
首先设计数据库表:
[sql]
CREATE TABLE IF NOT EXISTS `session` (
`phpsession` char(32) COLLATE utf8_bin NOT NULL,
`uptime` int(10) unsigned NOT NULL,
`data` text COLLATE utf8_bin NOT NULL, PRIMARY KEY (`phpsession`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
需要2个class, 一个是数据库的,一个是session的操作类
- <?php
- /**
- * session入库操作类
- * @author 删代码工程师 geek-cy.com
- */
- include 'DbSession.php'; //引入session数据库操作类
- class MySession extends DbSession{
- private $dbc = null; //保存数据库资源句柄
- private $lifetime = null; // session的生成时间
- private $time = null; //当前时间
- const uptime = 30; //更新session的时间
- static $DEBUG = false; //是否开启错误提示
- public function __construct( ){
- $this->init();
- $this->SessionSetSaveHandler();
- }
- /**
- * 初始化session处理
- * @throws Exception
- */
- private function init(){
- try{
- //设置数据库链接资源句柄
- $db = DbSession::InitDbSession(); //获取用于数据库操作的对象
- if( !($db instanceof DbSession) ){
- throw new Exception('需要MySession类的对象');
- }else{
- $this->dbc = $db;
- }
- //设置session有效时间
- if( !$this->lifetime = ini_get('session.gc_maxlifetime') ){
- throw new Exception('session.gc_maxlifetime获取失败');
- }
- }catch (Exception $e){
- $this->ShowErrow( $e->getMessage() );
- }
- $this->time = time();
- // ini_set('session.save_handler', user);
- }
- /**
- * 设置自定义session的回调方法
- */
- private function SessionSetSaveHandler(){
- session_set_save_handler(
- array($this, "open"),
- array($this, "close"),
- array($this, "read"),
- array($this, "write"),
- array($this, "destroy"),
- array($this, "gc")
- );
- session_start();//开启session
- }
- /**
- * 打开session
- * @param string $savePath
- * @param string $sessName
- * @return boolean
- */
- public function open($savePath, $sessName){
- if(is_null( $this->dbc )){ //判断数据库连接是否正常
- return false;
- }else{
- return true;
- }
- }
- /**
- * 关闭session
- */
- public function close(){
- $this->gc($this->lifetime); //触发垃圾回收机制
- return $this->dbc->MysqlClose(); //关闭数据库连接
- }
- /**
- * 读取session
- * @param string $sessionid
- * @return boolean|unknown
- */
- public function read( $sessionid ){
- $selectData = array(0=>$this->phpsession,1=>$this->uptime,2=>$this->data); // 需要读取的字段,数组形式
- $sessionData = $this->dbc->ReadSession($sessionid, $selectData);
- //是否返回有效值
- if( $sessionData == false){
- return false;
- }
- //是否过期判断
- if( $sessionData[$this->uptime] + $this->lifetime < $this->time ){
- $this->destroy( $sessionData[$this->phpsession] );
- return false;
- }
- return $sessionData[$this->data];
- }
- /**
- * 写入session
- * @param string $sessionid
- * @param string $data
- * @return boolean
- */
- public function write( $sessionid, $data ){
- $selectData = array(0=>$this->phpsession,1=>$this->uptime,2=>$this->data);// 需要读取的字段,数组形式
- $sessionData = $this->dbc->ReadSession($sessionid, $selectData);
- if( $sessionData == false){ //没有session数据
- if( !empty( $data ) ){ //判断是否用需要插入的session值
- //数组形式组装要插入的字段和对应值
- $insertData = array(
- $this->phpsession => $sessionid,
- $this->uptime => $this->time,
- $this->data => $data
- );
- $this->dbc->InsertSession( $insertData );
- }
- }else{//已经有了session数据
- //判断session数据是否有改变,或者需要更新有效时间。
- if($sessionData[$this->data] != $data || $this->time > ($sessionData[$this->uptime]+self::uptime)){
- //以数组形式组装要更新的数据
- $updateData = array(
- $this->uptime => $this->time,
- $this->data => $data
- );
- $this->dbc->UpdateSession($sessionData[$this->phpsession], $updateData );
- }
- }
- return true;
- }
- /**
- * 销毁session
- * @param string $sessionid
- */
- public function destroy( $sessionid ){
- return $this->dbc->DeleteSession( $sessionid );
- }
- /**
- * session的回收机制
- * @param string $lifetime
- */
- public function gc( $lifetime ){
- $this->dbc->GcSession( $lifetime );
- }
- }
- ?>
- <?php
- /**
- * session入库的数据库操作类
- * @author 删代码工程师 geek-cy.com
- *
- */
- class DbSession{
- public static $db = null;
- private $con = null; //保存数据库链接资源句柄
- private $HOSTNAME = 'localhost';
- private $DB = 'phptest';
- private $USER = 'root';
- private $PASSWORD = '';
- const CHARSET = 'UTF8'; //编码设置
- static $DEBUG = true; //是否开启错误提示
- //session表与表字段
- private $TableName = 'session';
- protected $phpsession = 'phpsession';
- protected $uptime = 'uptime';
- protected $data = 'data';
- private function __construct(){
- $this->contect();
- }
- private function __clone(){
- }
- /**
- * 初始化链接数据库
- * @return Ambigous <NULL, string>
- */
- public static function InitDbSession(){
- if( is_null(self::$db) || !(self::$db instanceof self) ){
- self::$db = new DbSession;
- }
- return self::$db; //返回类对象
- }
- /**
- * 链接数据库
- *
- */
- private function contect(){
- $this->con = mysql_connect($this->HOSTNAME, $this->USER, $this->PASSWORD); //保存数据库连接资源句柄
- try{
- if( is_null($this->con) ){
- throw new Exception('链接数据库失败');
- }
- if(!mysql_select_db($this->DB, $this->con)){
- throw new Exception('选择数据库失败');
- }
- mysql_query("SET NAMES self::CHARSET");
- }catch (Exception $e){
- $this->ShowErrow( $e->getMessage() );
- }
- }
- /**
- * 输出错误
- * @param string $msg
- */
- protected function ShowErrow( $msg ){
- if(static::$DEBUG){ //判断是否打印错误
- echo $msg;
- }
- }
- /**
- * 读取数据库中保存的session
- * @param string $sessionid
- * @param array $selectData
- * @return boolean|Ambigous <boolean, multitype:>
- */
- public function ReadSession( $sessionid, array $selectData ){
- $selectData = $this->doSelectData($selectData);
- if(!$selectData){
- return false;
- }
- if( $this->CheckSessionId($sessionid) ){
- $sql = 'SELECT '.$selectData.' FROM `'.$this->TableName.'` WHERE '.$this->phpsession.' = \''.$sessionid.'\' LIMIT 1';
- $result = mysql_query($sql, $this->con);
- return $this->fetch($result);
- }
- }
- /**
- * 写入新session到数据库中
- * @param array $insertData
- * @return boolean
- */
- public function InsertSession( array $insertData ){
- if( $insertData = $this->doInsertData($insertData) ){
- $sql = 'INSERT INTO '.$this->TableName.'('.$insertData[0].') VALUES('.$insertData[1].')';
- mysql_query($sql, $this->con);
- return true;
- }else{
- return false;
- }
- }
- /**
- * 更新数据库中保存的session
- * @param string $sessionid
- * @param array $updateData
- * @return boolean
- */
- public function UpdateSession( $sessionid, array $updateData){
- if( !$this->CheckSessionId($sessionid) ){
- return false;
- }
- if( $updateData = $this->doUpadateData($updateData) ){
- $sql = 'UPDATE '.$this->TableName.' SET '.$updateData.' WHERE '.$this->phpsession.' = \''.$sessionid.'\'';
- mysql_query($sql, $this->con);
- return true;
- }else{
- return false;
- }
- }
- /**
- * 删除数据库中的session
- * @param string $sessionid
- * @return boolean
- */
- public function DeleteSession( $sessionid ){
- if( !$this->CheckSessionId($sessionid) ){
- return false;
- }
- $sql = 'DELETE FROM '.$this->TableName.' WHERE \''.$sessionid.'\' = '.$this->phpsession;
- mysql_query($sql,$this->con);
- return true;
- }
- /**
- * 回收清除数据库中已经获取无用的session
- * @param string $lifetime
- * @return boolean
- */
- public function GcSession( $lifetime ){
- if( !ctype_digit($lifetime )){
- return false;
- }
- $checktime = time()-$lifetime;
- $sql = 'DELETE FROM '.$this->TableName.' WHERE '.$this->uptime.' < '.$checktime ;
- mysql_query($sql,$this->con);
- return true;
- }
- /**
- * 关闭数据库连接
- */
- public function MysqlClose(){
- mysql_close( $this->con );
- }
- public function __destruct(){
- self::$db = null;
- if($this->con instanceof self){
- mysql_close( $this->con );
- }
- }
- /**
- * 对session id 做合法性检查
- * @param string $sessionid
- * @return boolean
- */
- private function CheckSessionId( $sessionid ){
- return ctype_alnum($sessionid);
- }
- /**
- * 返回select取得的结果集
- * @param $result
- * @return boolean|multitype:
- */
- private function fetch( $result ){
- if( $result && mysql_num_rows($result) == 1){
- $resultArray = array();
- $resultArray = mysql_fetch_array($result, MYSQL_ASSOC);
- if( !$resultArray || count($resultArray)== 0 ){
- return false;
- }else{
- return $resultArray;
- }
- }else{
- return false;
- }
- }
- /**
- * 处理select要查询的字段
- * @param array $data
- * @return boolean|string
- */
- private function doSelectData( array $data ){
- $keyString = '';
- foreach ($data as $value){
- $keyString .= '`'.$value.'`,';
- }
- $keyString = substr($keyString,0,-1);
- if($keyString == ''){
- return false;
- }
- return $keyString;
- }
- /**
- * 处理要insert进数据库的字段和对应的值
- * @param array $data
- * @return boolean|string
- */
- private function doInsertData( array $data ){
- $keyString = '';
- $valueString = '';
- if(array_key_exists($this->phpsession, $data)){
- if( !$this->CheckSessionId($data[$this->phpsession]) ){
- return false;
- }
- }
- foreach ($data as $key => $value){
- $keyString .= '`'.$key.'`,';
- if(ctype_digit($value)){
- $valueString .= ''.$value.',';
- }else{
- $valueString .= '\''.$value.'\',';
- }
- }
- if( $keyString != '' && $valueString != ''){
- $keyString = substr($keyString,0,-1);
- $valueString = substr($valueString,0,-1);
- $dataArray[0] = $keyString; //字段
- $dataArray[1] = $valueString;//值
- return $dataArray;
- }else{
- return false;
- }
- }
- /**
- * 处理update的字段和对应的值
- * @param array $data
- * @return boolean|string
- */
- private function doUpadateData( array $data ){
- $upDataString = '';
- foreach($data as $key => $value){
- if(ctype_digit($value)){
- $value = ''.$value.'';
- }else{
- $value = '\''.$value.'\'';
- }
- $upDataString .= '`'.$key.'` = '.$value.',';
- }
- $upDataString = substr($upDataString,0,-1);
- if( $upDataString == ''){
- return false;
- }
- return $upDataString;
- }
- }
下面是使用方法:
- <?php
- include 'MySession.php';
- $session = new MySession( );
- $_SESSION['test1'] = 'test1';
- $_SESSION['test2'] = 2;
- $_SESSION['test3'] = array(1,2,3,4);
- // session_destroy();
- ?>
php实现session入库的更多相关文章
- Session 入库
session入库 session机制中的数据分部分存储,1部分在客户端的cookie中,2部分在服务器端的session文件中. 务器端的session文件中存储的是$_SESSION变量中的数据. ...
- php SESSION入库的实现
session入库,就是重写session制机,在session的周期内,获得到session的数据并记录到数据库 Session默认是存放到服务器上的文件中,不方便管理,如果能把session存放到 ...
- session高级(session入库)
我们知道,session是一种会话技术,用来实现跨脚本共享数据. 在之前的php会话技术中我们介绍过,session是存放在服务器端的文件里的,因此session有可能因为文件数量过多,会在查询ses ...
- php中session 入库的实现
ini_set("session.save_handler","user");//session.gc_probability = 1 分子ini_set(&q ...
- PHP 实现Session入库/存入redis
对于大访问量的站点使用默认的Session 并不合适,我们可以将其存入数据库.或者使用Redis KEY-VALUE数据存储方案 首先新建一个session表 CREATE TABLE `sessio ...
- session入库
#存储session的数据表示列结构,可作为参考#创建数据库(可选)CREATE DATABASE session;#使用创建的数据库(可选)USE session;#创建存储session的数据表( ...
- Session自定义存储及分布式存储
默认情况下,PHP 使用内置的文件会话保存管理器(files)来完成会话的保存.我们无需设置,PHP默认将session以文件的形式保存到服务器. 通过调用函数 session_start() 即可手 ...
- PHP的学习--cookie和session
最近读了一点<PHP核心技术与最佳实践>,看了cookie和session,有所收获,结合之前的认识参考了几篇博客,总结一下-- 1. PHP的COOKIE cookie 是一种在远程浏览 ...
- Cookie与Session详解
来源:<PHP核心技术与最佳实践> 列旭松 陈文 著 Cookie与Session详解读书笔记,从概念.操作.应用.注意事项以及区别等几方面详细阐述两者的基础知识,它们都是针对HTTP协议 ...
随机推荐
- SharePoint 2013创建应用程序时IIS端口文件夹下没文件
最近SharePoint 2007迁移到2013的时候,碰到创建应用程序时IIS端口文件夹下没文件的问题,网上找了大把的原因,终于在这里找到了解决方案: Fix: 1. Open IIS on the ...
- Apache Thrift - 可伸缩的跨语言服务开发框架 ---转载
src:http://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/ http://thrift.apache.org/
- Chrome 谷歌如何快速实现跨域
第一步:在你的E盘或者其他盘新建一个文件夹,命名为:E:\MyChromeDevUserData 第二步:找到你的谷歌浏览器快捷图标,鼠标右键选择属性,出现以下界面: 第三步:在目标选项的最后添加: ...
- 使用Visual Studio 2010打造C语言编译器
相信学习C语言的同学们一直在为自己的windows7不能用vc 6.0而烦恼着.或许有的电脑能使用上,但绝大多数是不能的,而且会出现软件不能兼容的提醒.其实大家都不需要再使用vc6.0了,因为软件更新 ...
- redis使用场景之位操作(大数据处理)
在学习redis的过程了,看到了redis还能用于大数据处理,具体场景如下: 腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,你能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下 ...
- Flume - 快速入门
关于Flume,官方定义如下: Apache Flume is a distributed, reliable, and available system for efficiently collec ...
- [C语言] 数据结构-算法效率的度量方法-事前分析估算方法
事前分析估算方法:在计算机程序编制前,依据统计方法对算法进行估算,抛开与计算机硬件软件有关的因素,一个程序的运行时间,依赖于算法的,好坏和问题的输入规模,所谓问题输入规模是指输入量的多少 推导过程,比 ...
- 数组的strong copy理解
一.数组的不同情况下的copy,mutablecopy分析 1.不可变数组的copy(没有创建新对象,复制的只是指针) 2.不可变数组的mutable copy(创建新对象) ...
- Java基础教程(22)--异常
一.什么是异常 异常就是发生在程序的执行期间,破坏程序指令的正常流程的事件.当方法中出现错误时,该方法会创建一个对象并将其交给运行时系统.该对象称为异常对象,它包含有关错误的信息,包括错误的类型和 ...
- 深入分析 Java 中的中文编码问题【转】
转:https://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/ 几种常见的编码格式 为什么要编码 不知道大家有没有想过一个问题,那就是 ...