Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; Chris@0: Chris@0: /** Chris@0: * Memcached based session storage handler based on the Memcached class Chris@0: * provided by the PHP memcached extension. Chris@0: * Chris@0: * @see http://php.net/memcached Chris@0: * Chris@0: * @author Drak Chris@0: */ Chris@14: class MemcachedSessionHandler extends AbstractSessionHandler Chris@0: { Chris@0: private $memcached; Chris@0: Chris@0: /** Chris@0: * @var int Time to live in seconds Chris@0: */ Chris@0: private $ttl; Chris@0: Chris@0: /** Chris@0: * @var string Key prefix for shared environments Chris@0: */ Chris@0: private $prefix; Chris@0: Chris@0: /** Chris@0: * Constructor. Chris@0: * Chris@0: * List of available options: Chris@0: * * prefix: The prefix to use for the memcached keys in order to avoid collision Chris@14: * * expiretime: The time to live in seconds. Chris@0: * Chris@0: * @param \Memcached $memcached A \Memcached instance Chris@0: * @param array $options An associative array of Memcached options Chris@0: * Chris@0: * @throws \InvalidArgumentException When unsupported options are passed Chris@0: */ Chris@17: public function __construct(\Memcached $memcached, array $options = []) Chris@0: { Chris@0: $this->memcached = $memcached; Chris@0: Chris@17: if ($diff = array_diff(array_keys($options), ['prefix', 'expiretime'])) { Chris@17: throw new \InvalidArgumentException(sprintf('The following options are not supported "%s"', implode(', ', $diff))); Chris@0: } Chris@0: Chris@0: $this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400; Chris@0: $this->prefix = isset($options['prefix']) ? $options['prefix'] : 'sf2s'; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function close() Chris@0: { Chris@17: return $this->memcached->quit(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@14: protected function doRead($sessionId) Chris@0: { Chris@0: return $this->memcached->get($this->prefix.$sessionId) ?: ''; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@14: public function updateTimestamp($sessionId, $data) Chris@14: { Chris@14: $this->memcached->touch($this->prefix.$sessionId, time() + $this->ttl); Chris@14: Chris@14: return true; Chris@14: } Chris@14: Chris@14: /** Chris@14: * {@inheritdoc} Chris@14: */ Chris@14: protected function doWrite($sessionId, $data) Chris@0: { Chris@0: return $this->memcached->set($this->prefix.$sessionId, $data, time() + $this->ttl); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@14: protected function doDestroy($sessionId) Chris@0: { Chris@14: $result = $this->memcached->delete($this->prefix.$sessionId); Chris@14: Chris@14: return $result || \Memcached::RES_NOTFOUND == $this->memcached->getResultCode(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function gc($maxlifetime) Chris@0: { Chris@0: // not required here because memcached will auto expire the records anyhow. Chris@0: return true; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Return a Memcached instance. Chris@0: * Chris@0: * @return \Memcached Chris@0: */ Chris@0: protected function getMemcached() Chris@0: { Chris@0: return $this->memcached; Chris@0: } Chris@0: }