PHP uses redis to realize session sharing

Time:2019-12-10

Last modified: 16:06:36, May 10, 2019

Preface

For small-scale web services, session data is basically stored locally (more local disk files), but when multiple services are deployed and session sharing is required, ensure that each service can share the same session data

Redis data is stored in memory with good performance. With persistence, data integrity can be ensured

design scheme

1. Through PHP’s own session configuration

#Using redis as a storage solution
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"
#If the connection password is set, use the following
Session.save_path = "TCP: // 127.0.0.1:6379? Auth = password"

Test code

<?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>";

Output output

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

evaluate

  • Advantage:Simple implementation, no need to modify PHP code
  • Disadvantages:Configuration does not support diversification and can only be applied to simple scenarios

2. Set user-defined session storage function

Set the user-defined session function through the session set save handler() function

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

After the session storage function is configured, executesession_start()Yes.

The specific code is omitted, and a copy is provided belowMemcachedFrom symfony framework code:

<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <[email protected]>
 *
 * 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 <[email protected]>
 */
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;
    }
}

Recommended Today

PHP calls cjieba word segmentation through FFI

This paper attempts to use the FFI test of PHP 7.4 to directly call the dynamic library of cjieba word segmentation. The reason for choosing cjieba is that FFI uses the calling convention of C. If you use CPP, you have to wrap it yourself, and then use external C to let the compiler generate […]