php+redis实现session共享

本文介绍了两种在PHP中利用Redis实现Session共享的方法。方案1通过ini_set设置session存储方式和路径;方案2则利用session_set_save_handler自定义session处理器。在PHP 5.4.45版本中,使用SessionHandlerInterface会导致502错误,需采用不同参数调用session_set_save_handler。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、方案1

方案1特别简单,直接用ini_set设置session的存储方式和存储路径即可,如下:

ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379?auth=123456');
这样,我们的session信息就可以保存到redis中了。如下图:



二、方案2

方案2是使用session_set_save_handler来实现session的存储。

1、配置redis参数

//redis配置
$GLOBALS['config']['redis'] = [
    'host'         => '127.0.0.1', // redis主机
    'port'         => 6379, // redis端口
    'password'     => '', // 密码
    'select'       => 0, // 操作库
    'expire'       => 3600, //有效期
    'timeout'      => 0, // 连接超时时间(单位:毫秒)
    'prefix' => 'PHPREDIS_SESSION:', // key前缀
];

2、存储类

<?php
class SessionRedis extends SessionHandler
{
    protected $handler = null;
    protected $config  = [
        'host'         => '127.0.0.1', // redis主机
        'port'         => 6379, // redis端口
        'password'     => '', // 密码
        'select'       => 0, // 操作库
        'expire'       => 3600, // session有效期
        'timeout'      => 0, // 连接超时时间(单位:毫秒)
        'prefix' => '', // key前缀
    ];

    public function __construct($config = [])
    {
        $this->config = array_merge($this->config, $config);
        //var_dump($this->config);
    }

    /**
     * 打开Session
     * @access public
     * @param string    $savePath
     * @param mixed     $sessName
     */
    public function open($savePath, $sessName)
    {
        // 检测php环境
        if (!extension_loaded('redis')) {
            throw new Exception('not support:redis');
        }

        $this->handler = new Redis();

        //连接
        $this->handler->connect($this->config['host'], $this->config['port'], $this->config['timeout']);

        //密码
        if('' != $this->config['password']) {
            $this->handler->auth($this->config['password']);
        }

        //选择数据库
        if(0 != $this->config['select']) {
            $this->handler->select($this->config['select']);
        }

        return true;
    }

    /**
     * 关闭Session
     * @access public
     */
    public function close()
    {
        $this->gc(ini_get('session.gc_maxlifetime'));
        $this->handler->close();
        $this->handler = null;
        return true;
    }

    /**
     * 读取Session
     * @access public
     * @param mixed $sessID
     */
    public function read($sessID)
    {
        return $this->handler->get($this->config['prefix'] . $sessID);
    }

    /**
     * 写入Session
     * @access public
     * @param string $sessID
     * @param String $sessData
     * @return bool
     */
    public function write($sessID, $sessData)
    {
        if($this->config['expire']) {
            return $this->handler->setex($this->config['prefix'] . $sessID, $this->config['expire'], $sessData);
        } else {
            return $this->handler->set($this->config['prefix'] . $sessID, $sessData);
        }
    }

    /**
     * 删除Session
     * @access public
     * @param string $sessID
     * @return bool
     */
    public function destroy($sessID)
    {
        return $this->handler->delete($this->config['prefix'] . $sessID);
    }

    /**
     * Session 垃圾回收
     * @access public
     * @param string $sessMaxLifeTime
     * @return true
     */
    public function gc($sessMaxLifeTime)
    {
        return true;
    }
    
    
}

3、实现

<?php
/**
 * session放入redis */
header("Content-type: text/html; charset=utf-8");

error_reporting(E_ALL);

define('DIR', dirname(__FILE__));

//引入配置文件
require_once DIR.'/config.php';

//引入库文件
require_once DIR.'/lib/SessionRedis.php';

//方法1:直接设置session保存方式
//ini_set('session.save_handler', 'redis');
//ini_set('session.save_path', 'tcp://127.0.0.1:6379');

//方法2:通过session句柄的方式
//初始化session句柄
$s_handler = new SessionRedis($GLOBALS['config']['redis']);
session_set_save_handler(
    array($s_handler, 'open'),
    array($s_handler, 'close'),
    array($s_handler, 'read'),
    array($s_handler, 'write'),
    array($s_handler, 'destroy'),
    array($s_handler, 'gc')
);
register_shutdown_function('session_write_close');

session_start();

$user_info = $_SESSION['u2'];

if(empty($user_info)) {
    if(!empty($_POST)) {
        $_SESSION['u2'] = $_POST;
        header('Location: /redis_session.php');
    } else {
        echo <<<EOT
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title> 用户登录 </title>
    </head>
    <body>
        <form action="" method="POST">
            用户名: <input type="text" name="username" value="" />
            密码:  <input type="password" name="password" value="" />
            <input type="submit" value="提交" />
        </form>
    </body>
</html>
EOT;
    }
} else {
    //查看session的位置
    var_dump($user_info);
    $_SESSION['u1'] = ['test' => 'i am test', 'test2' => 'i am test2'];
}


好了,一切就是这么简单。


但是,有个很奇怪的问题,我的php版本是5.4.45的,在用session_set_save_handler的时候,如果使用如下的方式:

session_set_save_handler ( SessionHandlerInterface $sessionhandler [, bool $register_shutdown = true ] )

程序会报502错误,只能改成

bool session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroycallable $gc [, callable $create_sid [, callable $validate_sid [, callable $update_timestamp ]]] )这种方式。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值