自定义session的存储机制

<?php

class MSession implements SessionHandlerInterface
{
    // reids 对象
    protected $handler = null;
    // 配置
    protected $config = [
        'host' => '127.0.0.1', // redis主机
        'port' => 6379, // redis端口
        'password' => '', // 密码
        'select' => 0, // 操作库
        'expire' => 3600, // 有效期(秒)
        'timeout' => 0, // 超时时间(秒)
        'persistent' => true, // 是否长连接
        'session_name' => '', // sessionkey前缀
    ];

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

    /**
     * 类似于类的构造函数
     * 当session_start()函数被调用的时候该函数被触发
     *
     * @param string $save_path
     * @param string $name  PHPSESSID
     * @throws BadFunctionCallException
     * @return bool
     */
    public function open($save_path, $name)
    {
        // TODO: Implement open() method.
        if (extension_loaded('redis')) {
            $this->handler = new Redis;

            // 建立连接
            $func = $this->config['persistent'] ? 'pconnect' : 'connect';
            $this->handler->$func($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']);
            }
        } elseif (class_exists('PredisClient')) {
            $params = [];
            foreach ($this->config as $key => $val) {
                if (in_array($key, ['aggregate', 'cluster', 'connections', 'exceptions', 'prefix', 'profile', 'replication'])) {
                    $params[$key] = $val;
                    unset($this->config[$key]);
                }
            }
            $this->handler = new PredisClient($this->config, $params);
        } else {
            throw new BadFunctionCallException('not support: redis');
        }

        return true;
    }

    /**
     * 从session存储空间读取session的数据。
     * 当调用session_start()函数的时候该函数会被触发
     * 但是在session_start()函数调用的时候先触发open函数,再触发该函数
     *
     * @param string $session_id
     * @return string 有数据返回session数据序列化后的字符串,若没有数据,返回空白字符串
     */
    public function read($session_id)
    {
        // TODO: Implement read() method.
        return (string)$this->handler->get($this->config['session_name'] . $session_id);
    }

    /**
     * 清除垃圾session,也就是清除过期的session。
     * 该函数是基于php.ini中的配置选项
     * session.gc_divisor, session.gc_probability 和 session.gc_lifetime所设置的值的
     *
     * @param int $maxlifetime
     * @return bool
     */
    public function gc($maxlifetime)
    {
        // TODO: Implement gc() method.
        return true;
    }

    /**
     * 在session保存数据时或在脚本结束时会调用
     * 在调用完此函数之后,PHP 内部会调用close函数。
     *
     * @param string $session_id
     * @param string $session_data $_SESSION 中数据序列化之后的字符串
     * @return bool
     */
    public function write($session_id, $session_data)
    {
        // TODO: Implement write() method.
        if ($this->config['expire'] > 0) {
            $result = $this->handler->setex($this->config['session_name'] . $session_id, $this->config['expire'], $session_data);
        } else {
            $result = $this->handler->set($this->config['session_name'] . $session_id, $session_data);
        }

        return $result ? true : false;
    }

    /**
     * 调用 session_destroy() 函数时调用
     * write 和 destory互斥
     *
     * @param string $session_id
     * @return bool
     */
    public function destroy($session_id)
    {
        // TODO: Implement destroy() method.
        return $this->handler->delete($this->config['session_name'] . $session_id) > 0;
    }


    /**
     * 类似于类的析构函数
     * 当session关闭的时候该函数自动被触发
     *
     * @return bool
     */
    public function close()
    {
        // TODO: Implement close() method.
        $this->handler->close();
        $this->handler = null;
        return true;
    }
}
原文地址:https://www.cnblogs.com/cshaptx4869/p/10265200.html