PHP使用Redis实现Session共享的实现示例


Posted in PHP onMay 12, 2019

前言

小型web服务, session数据基本是保存在本地(更多是本地磁盘文件), 但是当部署多台服务, 且需要共享session, 确保每个服务都能共享到同一份session数据.

redis 数据存储在内存中, 性能好, 配合持久化可确保数据完整.

设计方案

1. 通过php自身session配置实现

# 使用 redis 作为存储方案
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"
# 若设置了连接密码, 则使用如下
session.save_path = "tcp://127.0.0.1:6379?auth=密码"

测试代码

<?php
ini_set("session.save_handler", "redis");
ini_set("session.save_path", "tcp://127.0.0.1:6379");

session_start();
echo "<pre>";
$_SESSION['usertest'.rand(1,5)]=1;
var_dump($_SESSION);

echo "</pre>";

输出 ↓

array(2) {
  ["usertest1"]=>
  int(88)
  ["usertest3"]=>
  int(1)
}
usertest1|i:1;usertest3|i:1;

评价

  • 优点: 实现简单, 无需修改php代码
  • 缺点: 配置不支持多样化, 只能应用于简单场景

2. 设置用户自定义会话存储函数

通过 session_set_save_handler() 函数设置用户自定义会话函数.

session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid [, callable $validate_sid [, callable $update_timestamp ]]] ) : bool
  
# >= php5.4
session_set_save_handler ( object $sessionhandler [, bool $register_shutdown = TRUE ] ) : bool

在配置完会话存储函数后, 再执行 session_start() 即可.

具体代码略, 以下提供一份 Memcached 的(来自Symfony框架代码):

<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;

/**
 * MemcacheSessionHandler.
 *
 * @author Drak <drak@zikula.org>
 */
class MemcacheSessionHandler implements \SessionHandlerInterface
{
  /**
   * @var \Memcache Memcache driver.
   */
  private $memcache;

  /**
   * @var int Time to live in seconds
   */
  private $ttl;

  /**
   * @var string Key prefix for shared environments.
   */
  private $prefix;

  /**
   * Constructor.
   *
   * List of available options:
   * * prefix: The prefix to use for the memcache keys in order to avoid collision
   * * expiretime: The time to live in seconds
   *
   * @param \Memcache $memcache A \Memcache instance
   * @param array   $options An associative array of Memcache options
   *
   * @throws \InvalidArgumentException When unsupported options are passed
   */
  public function __construct(\Memcache $memcache, array $options = array())
  {
    if ($diff = array_diff(array_keys($options), array('prefix', 'expiretime'))) {
      throw new \InvalidArgumentException(sprintf(
        'The following options are not supported "%s"', implode(', ', $diff)
      ));
    }

    $this->memcache = $memcache;
    $this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400;
    $this->prefix = isset($options['prefix']) ? $options['prefix'] : 'sf2s';
  }

  /**
   * {@inheritdoc}
   */
  public function open($savePath, $sessionName)
  {
    return true;
  }

  /**
   * {@inheritdoc}
   */
  public function close()
  {
    return $this->memcache->close();
  }

  /**
   * {@inheritdoc}
   */
  public function read($sessionId)
  {
    return $this->memcache->get($this->prefix.$sessionId) ?: '';
  }

  /**
   * {@inheritdoc}
   */
  public function write($sessionId, $data)
  {
    return $this->memcache->set($this->prefix.$sessionId, $data, 0, time() + $this->ttl);
  }

  /**
   * {@inheritdoc}
   */
  public function destroy($sessionId)
  {
    return $this->memcache->delete($this->prefix.$sessionId);
  }

  /**
   * {@inheritdoc}
   */
  public function gc($maxlifetime)
  {
    // not required here because memcache will auto expire the records anyhow.
    return true;
  }

  /**
   * Return a Memcache instance
   *
   * @return \Memcache
   */
  protected function getMemcache()
  {
    return $this->memcache;
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
用PHP和ACCESS写聊天室(四)
Oct 09 PHP
PHP中的日期及时间
Nov 23 PHP
解析获取优酷视频真实下载地址的PHP源代码
Jun 26 PHP
php 强制下载文件实现代码
Oct 28 PHP
php学习笔记之面向对象
Nov 08 PHP
浅析php原型模式
Nov 25 PHP
php实现比较两个文件夹异同的方法
Jun 18 PHP
Yii2前后台分离及migrate使用(七)
May 04 PHP
PHP is_array() 检测变量是否是数组的实现方法
Jun 13 PHP
PHP jpgraph库的配置及生成统计图表:折线图、柱状图、饼状图
May 15 PHP
redis+php实现微博(一)注册与登录功能详解
Sep 23 PHP
Laravel 使用查询构造器配合原生sql语句查询的例子
Oct 12 PHP
如何让PHP编码更加好看利于阅读
May 12 #PHP
Yii2处理密码加密及验证的方法
May 12 #PHP
php和asp语法上的区别总结
May 12 #PHP
Laravel推荐使用的十个辅助函数
May 10 #PHP
PHP下载大文件失败并限制下载速度的实例代码
May 10 #PHP
PHP 7.4 新语法之箭头函数实例详解
May 09 #PHP
PHP文件类型检查及fileinfo模块安装使用详解
May 09 #PHP
You might like
生成sessionid和随机密码的例子
2006/10/09 PHP
用 PHP5 轻松解析 XML
2006/12/04 PHP
dede全站URL静态化改造[070414更正]
2007/04/17 PHP
php验证码实现代码(3种)
2015/09/07 PHP
腾讯CMEM的PHP扩展编译安装方法
2015/09/25 PHP
PHP5.4起内置web服务器使用方法
2016/08/09 PHP
laravel 实现划分admin和home 模块分组
2019/10/15 PHP
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera
2009/08/28 Javascript
ExtJS 2.0 GridPanel基本表格简明教程
2010/05/25 Javascript
Javascript中valueOf与toString区别浅析
2013/03/19 Javascript
document.documentElement和document.body区别介绍
2013/09/16 Javascript
jquery制作居中遮罩层效果分享
2014/02/21 Javascript
jQuery中hover方法和toggle方法使用指南
2015/02/27 Javascript
详细解密jsonp跨域请求
2015/04/15 Javascript
Javascript中this绑定的3种方法与比较
2016/10/13 Javascript
关于RequireJS的简单介绍即使用方法
2016/10/20 Javascript
react-router4按需加载(踩坑填坑)
2019/01/06 Javascript
JS原型与继承操作示例
2019/05/09 Javascript
node中IO以及定时器优先级详解
2019/05/10 Javascript
vuex中store存储store.commit和store.dispatch的用法
2020/07/24 Javascript
解决vue+webpack项目接口跨域出现的问题
2020/08/10 Javascript
[01:29]2014DOTA2展望TI 剑指西雅图DK战队专访
2014/06/30 DOTA
[56:00]DOTA2上海特级锦标赛主赛事日 - 4 胜者组决赛Secret VS Liquid第一局
2016/03/05 DOTA
python使用Plotly绘图工具绘制散点图、线形图
2019/04/02 Python
pytorch对梯度进行可视化进行梯度检查教程
2020/02/04 Python
使用python自动追踪你的快递(物流推送邮箱)
2020/03/17 Python
python requests.get带header
2020/05/05 Python
Python 如何查找特定类型文件
2020/08/17 Python
Python爬虫如何破解JS加密的Cookie
2020/11/19 Python
全面解析CSS Media媒体查询使用操作(推荐)
2017/08/15 HTML / CSS
html5 Canvas画图教程(5)—canvas里画曲线之arc方法
2013/01/09 HTML / CSS
阿联酋团购网站:Groupon阿联酋
2016/10/14 全球购物
Exception类的常用方法
2012/06/16 面试题
教育专业毕业生推荐信
2014/07/10 职场文书
2014年班组工作总结
2014/11/20 职场文书
2015年服务员个人工作总结
2015/05/27 职场文书