• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    PHP中如何使用Redis接管文件存储Session详解

    前言

    php默认使用文件存储session,如果并发量大,效率会非常低。而redis对高并发的支持非常好,可以利用redis替换文件来存储session。

    最近就遇到了这个问题,之前找了网上的一套直播系统给客户用,刚开始是没问题的,在后面人数上来之后网站开始变得卡顿,卡的一批。之后查看php慢日志发现session_start()的身影,好吧,原来是万恶的文件存储session,跟我之前进的坑一模一样……之前做的教务查询系统直接用的session没有用cookie,结果在高并发的情况下php原地爆炸。

    [0x00007fff67ee6740] session_start()
    [0x00007fff67ee7b70] +++ dump failed

    解决方案

    坑中坑

    因为这套直播系统一没有用框架,二没有设计规范,各种session操作散落在不同的文件里,用第一个解决方案完全属于费力不讨好。再者直播系统的聊天互动等功能已经涉及大量的mysql操作,再用mysql接管session变相的增加了数据库的压力,最终确定了使用redis接管session。

    具体实现

    php有内置的操作session的save_handler,使用session_set_save_handler,接管所有的session管理工作。在使用该函数前,先把php.ini配置文件的session.save_handler选项设置为user,否则session_set_save_handle不会生效。另外除了安装redis之外,php扩展也需要增加redis。

    (以下代码来源于网络,也不知道原创是哪位大佬)

    编写一个session管理类sessionManager.php,代码如下:

    ?php
    class SessionManager{
    
     private $redis;
     private $sessionSavePath;
     private $sessionName;
     private $sessionExpireTime=30;//redis,session的过期时间为30s
    
     public function __construct(){
      $this->redis = new Redis();//创建phpredis实例
      $this->redis->connect('127.0.0.1',6379);//连接redis
      $this->redis->auth("107lab");//授权
      $retval = session_set_save_handler(
       array($this,"open"),
       array($this,"close"),
       array($this,"read"),
       array($this,"write"),
       array($this,"destroy"),
       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);//获取redis中的指定记录
      if($value){
       return $value;
      }else{
       return '';
      }
     }
    
     public function write($id,$data){
      if($this->redis->set($id,$data)){//以session ID为键,存储
       $this->redis->expire($id,$this->sessionExpireTime);//设置redis中数据的过期时间,即session的过期时间
       return true;
      }
    
      return false;
     }
    
     public function destroy($id){
      if($this->redis->delete($id)){//删除redis中的指定记录
       return true;
      }
      return false;
     }
    
     public function gc($maxlifetime){
      return true;
     }
    
     public function __destruct(){
      session_write_close();
     }
    
    }

    SessionManager构造函数主要用来连接Redis服务器,使用session_set_save_handler函数设置session回调函数,并调用session_start函数开启session功能。因为本例中open、close和gc回调函数的作用不是很大,所以直接返回true。

    在write回调函数中,以session ID 作为key,把session的数据作为value存储到redis服务器,设置session的过期时间为30秒。在read回调函中,以session ID 作为key从redis服务器中读取数据,并返回此数据。而在destroy回调函数重,则以session ID 作为key 从redis服务器中删除对应的session数据。

    使用时,只需包含SessionManager类,然后实例化一个SessionManager对象。

    下面建立个session_set.php文件,代码如下:

    ?php
     include('SessionManager.php');
     new SessionManager();
     $_SESSION['username'] = 'captain';

    然后再创建一个session_get.php文件,代码如下:

    ?php
     include('SessionManager.php');
     new SessionManager();
     echo $_SESSION['username'];

    测试时,首先访问session_set.php,然后再访问session_get.php,输出结果如下所示:

    再查看redis数据库,如下所示:

    127.0.0.1:6379> keys *
    1) "oe94eic337slnjv1bvlreoa574"
    127.0.0.1:6379> get oe94eic337slnjv1bvlreoa574
    "username|s:7:\"captain\";"

    测试完美~

    然后将原系统中的session_start()替换成session_set.php的前两行,成功接管,舒服。

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

    您可能感兴趣的文章:
    • PHP使用Redis实现Session共享的实现示例
    • PHP SESSION机制的理解与实例
    • 实现PHP中session存储及删除变量
    • PHP实现用session来实现记录用户登陆信息
    • PHP实现负载均衡session共享redis缓存操作示例
    • php session_decode函数用法讲解
    上一篇:php基于Redis消息队列实现的消息推送的方法
    下一篇:PHP序列化的四种实现方法与横向对比
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯

    时间:9:00-21:00 (节假日不休)

    地址:江苏信息产业基地11号楼四层

    《增值电信业务经营许可证》 苏B2-20120278

    PHP中如何使用Redis接管文件存储Session详解 PHP,中,如何,使用,Redis,接管,