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

举报
lxw1844912514 发表于 2022/03/27 02:04:17 2022/03/27
【摘要】 https://www.jb51.net/article/151580.htm   前言   php默认使用文件存储session,如果并发量大,效率会非常低。而redis对高并发的支持非常好,可以利用redis替换文件来存储session。   最近就遇到了这个问题,之前找了...

https://www.jb51.net/article/151580.htm

 

前言

 

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

 

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

 

 

 

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

 

解决方案

 

  • 将session全面更换为cookie

  • 使用mysql或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,代码如下:

 

<?phpclass 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的前两行,成功接管

 

文章来源: blog.csdn.net,作者:lxw1844912514,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/lxw1844912514/article/details/100029033

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。