文档章节

PHP 实现Session入库/存入redis

eatnothing
 eatnothing
发布于 2015/11/10 15:11
字数 704
阅读 1639
收藏 72

对于大访问量的站点使用默认的Session 并不合适,我们可以将其存入数据库、或者使用Redis KEY-VALUE数据存储方案

首先新建一个session表

CREATE TABLE `sessions` (
  `sid` char(40) NOT NULL,
  `updatetime` int(20) NOT NULL,
  `data` varchar(200) NOT NULL,
  UNIQUE KEY `sid` (`sid`) USING HASH
) ENGINE=MEMORY DEFAULT CHARSET=utf8;

Mysql 的memory引擎采用内存表,所有数据存储在内存,操作速度快

<?php
//引入数据库文件
include "db.php";
class MySessionHandler implements SessionHandlerInterface
{
    private $savePath;
	private $sessData;
	public $expiretime;	//设置过期时间
	public $db;	//数据库
	public function __construct($hanlder =''){
		
		$this->db = Database::getInstance();	
		
		//获取数据库实力 
		///var_dump($this->db);
		
	}
	
    public function open($savePath, $sessionName)
    {

        return true;
    }

    public function close()
    {
        return true;
    }

    public function read($id)
    {    
		$sql ="select * from sessions where sid ='$id'";
		$result = $this->db->execute($sql);
			if(!empty($result)){
				 return $this->sessData = $result;
			}
    }
            //函数的参数 $id -> 当前会话ID
            //数据DATA -> 序列化之后的字符串
    public function write($id, $data)
    {
		// echo $id;
		// echo $data;
		$now = time();
		$newExp = $now+$this->expiretime;    //总时间=当前时间 + 期限时间
		$sql = "select * from sessions where sid ='$id'";
		$result = $this->db->getOne($sql);
		//var_dump($result);
		if($data==''||isset($data)){
			$data = $this->sessData;
		}
			if($result){
			//如果存在则更新
   $sql ="update sessions set updatetime = '$newExp',data ='$data' where sid = '$id'";
				//echo $sql;
					$update_data =$this->db->execute($sql);
					if($update_data){
						return true;
					}
				
			}else{
			//不存在则生成生成
	$sql = "insert into sessions(sid,updatetime,data) values('$id','$now','$data')";
		$insert_data = $this->db->execute($sql);
		if($insert_data){
		return true;
				}
			}
			return false;
    }

    public function destroy($id)
    {        //销毁
		$sql = "delete from sessions where sid="."$id";
		$destory = $this->db->execute($sql);
		if($destory){
			  return true;
		}else{
			return false;
		}
    }

    public function gc($sessMaxLifeTime)
    {
      $t = time();
	$sql ="delete from sessions where $t - 'updatetime'>${sessMaxLifeTime}";
		$data = $this->db->execute($this->tosql);
		if($data){
			return true;
		}else{
			return false;
			}
        return true;
    }
}

实例化

此处 PHP 手册可以有两种方法

    1,实现了SessionHandlerInterface借口的对象,自PHP5.4可以使用

    2 ,直接使用  session_set_save_handler

 //判断PHP版本
 if(version_compare(PHP_VERSION,5.4)==1){
			 
	 session_set_save_handler($handler, true);
	session_start();
	}else{	 
	    ini_set('session.use_trans_sid',0);
	    ini_set('session.use_cookies',1);
	    ini_set('session.cookie_path','/');
            ini_set('session.save_handler','user');
            session_module_name('user');
            session_set_save_handler(array($session,"open"),array($session,"close"),array($session,"read"),array($session,"write"),array($session,"destory"),array($session,"gc"));
            session_start();	 
		 }
$_SESSION['QQ']="QQ";
echo $_SESSION['QQ'];

数据库代码

<?php 
class Database{
		 static $instance;
		static $db;
	static  function getInstance(){		
		if(self::$instance){
			return self::$instance;
		}else{
			return new  Database();   
		}
	}
	public function __construct(){
		self::$db = new PDO('mysql:host=localhost;dbname=session', 'root','');
	}

		public  function getOne($sql){
			$rs =self::$db->query($sql);
			@$rs->setFetchMode(PDO::FETCH_ASSOC);//返回关联数组
			$result = $rs -> fetch();
			return $result;
		}
		public function execute($sql){
			
			
				$rs = self::$db->exec($sql);
				return $rs;
				
		} 
	

}


//$data = Database::getInstance();
//var_dump($data);

  使用REDIS 存储SESSION

<?php
class SessionManager{
	private $redis;
	private $sessionSavePath;
	private $sessionName;
	private $sessionExpireTime = 30;
	public function __construct(){
		$this->redis = new Redis();
		$this->redis->connect('127.0.0.1',6379);    //连接redis
		$retval = session_set_save_handler(
			array($this,"open"),
			array($this,"close"),
			array($this,"read"),
			array($this,"write"),
			array($this,"destory"),
			array($this,"gc")
		);
			session_start();
	}
	
		public function open($path,$name){
			return true;
		}
		public function close(){
			return true;
		}
		public function read($id){
			$value = $this->redis->get($id);
			if($value){
				return $value;
			}else{
				return "";
			}
		}
		public function write($id,$data){
			if($this->redis->set($id,$data)){
				$this->redis->expire($id,$this->sessionExpireTime);  
				  //设置过期时间
				return true;
			}
			return false;
		}
		public function destory($id){
			if($this->redis->delete($id)){
				return true;
			}
			return false;
		}
		public function gc($maxlifetime){
			return true;
		}
		//析构函数
		public function __destruct(){
			session_write_close();
		}
		
}


$re = new SessionManager();
$_SESSION['name'] = "qq";
echo $_SESSION['name'];

 

© 著作权归作者所有

上一篇: 面试总结(php)
下一篇: PHP SPL的使用
eatnothing
粉丝 39
博文 128
码字总数 68736
作品 0
昌平
程序员
私信 提问
加载中

评论(8)

yeszao
yeszao

引用来自“cloudlylyly”的评论

对redis方式。直接php.ini里面有设置session存放路径,貌似叫session_save_path 和 session_save_handler 设置成redis相关配置就好。不用其他代码处理
这个方法最快最简单,都不用改代码,我看到这篇文章写得很详细:http://www.awaimai.com/1871.html
MeteorGX
MeteorGX
感觉用Memcache好点,写在redis看业务情况,如果session需求大可以试试....
RainingMan
RainingMan
对redis方式。直接php.ini里面有设置session存放路径,貌似叫session_save_path 和 session_save_handler 设置成redis相关配置就好。不用其他代码处理
eatnothing
eatnothing 博主

引用来自“ZoaChou”的评论

不介意memcache的话 php.ini里有个设定session保存方式的选项,换成mc也挺快的
ZoaChou
ZoaChou
不介意memcache的话 php.ini里有个设定session保存方式的选项,换成mc也挺快的
Tuesday
Tuesday

引用来自“Tuesday”的评论

如果这样, 不如直接定义个方法来处理更好.

引用来自“eatnothing”的评论

不懂,大牛请赐教
直接定义get, set方法. 然后里面写数据...
eatnothing
eatnothing 博主

引用来自“Tuesday”的评论

如果这样, 不如直接定义个方法来处理更好.
不懂,大牛请赐教
Tuesday
Tuesday
如果这样, 不如直接定义个方法来处理更好.
PHP中使用Redis接管文件存储Session详解

前言 php默认使用文件存储session,如果并发量大,效率会非常低。而redis对高并发的支持非常好,可以利用redis替换文件来存储session。 最近就遇到了这个问题,之前找了网上的一套直播系统给...

开元中国2015
2018/12/04
59
0
PHP用COOKIE实现一套SESSION机制

PHP的 SESSION是根据访客浏览器传过来的SESSION ID(表现为一个COOKIE) 来找到服务器的会话文件(/tmp/SESSID),以便通过$SESSION数组读取里面的内容(会话变量). 利用PHP的SESSION可以很方便地实...

eechen
2015/04/15
1K
3
Redis抢购设计章

抢购是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少(“超卖”问题) 对于第一个问题,已经很容易想到用缓存来处...

君满楼001
2017/12/21
0
0
让php Session 存入 redis 配置方法

首先要做的就是安装redis 安装方法:http://redis.io/download InstallationDownload, extract and compile Redis with:$ wget http://download.redis.io/releases/redis-2.8.19.tar.gz$ tar ......

党程V
2015/01/30
15K
6
高并发简单解决方案————redis队列缓存+mysql 批量入库(ThinkPhP)

问题分析 问题一:要求日志最好入库;但是,直接入库mysql确实扛不住,批量入库没有问题,done。【批量入库和直接入库性能差异】 问题二:批量入库就需要有高并发的消息队列,决定采用redis...

nsns
2018/05/18
159
0

没有更多内容

加载失败,请刷新页面

加载更多

分页查询

一、配置 /*** @author beth* @data 2019-10-14 20:01*/@Configurationpublic class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor(){ ......

一个yuanbeth
21分钟前
2
0
在LINQPad中使用Ignite.NET

LINQPad是进行.NET开发的一款优秀工具,非常有利于Ignite.NET API的快速入门。 入门 下载LINQPad:linqpad.net/Download.aspx,注意要选择64位操作系统的AnyCPU版本; 安装Ignite.NET的NuGet...

李玉珏
34分钟前
3
0
JS其他类型值转化为Boolean类型规则

本文转载于:专业的前端网站➤JS其他类型值转化为Boolean类型规则 由于最近在笔试的时候,发现好多关于其他类型转化为Boolean类型的题目,因此总结一下! 一、String类型转化为Boolean 1.转化...

前端老手
45分钟前
5
0
EurekaClient自动装配及启动流程解析

在上篇文章中,我们简单介绍了EurekaServer自动装配及启动流程解析,本篇文章则继续研究EurekaClient的相关代码 老规矩,先看spring.factories文件,其中引入了一个配置类EurekaDiscoveryClie...

Java学习录
51分钟前
9
0
析构函数是否必须为虚函数?为何?

p517 在C++中,基类指针可以指向一个派生类的对象。如果基类的析构函数不是虚函数,当需要delete这个指向派生类的基类指针时,就只会调用基类的析构函数,而派生类的析构函数无法被调用。容易...

天王盖地虎626
52分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部