前言
在遇到了 SESSION 混乱的问题后,突然对自定义会话管理器有了兴趣,于是便研究实现了一番。
分析
根据PHP官网的说明,实现方式有两种,这里准备用继承类的方式做,同时将 SESSION 存储于 Memcache 中。
实现
首先先要写一个继承于 SessionHandlerInterface 的类。
class MemcachedHanlder implements SessionHandlerInterface { }
|
在 MemcachedHanlder 类实例化的时候,附上需要连接 Memcached 的参数。
protected $_options; protected $_memcached; protected $_prefix;
function __construct(array $options = []) { if (!isset($options['host'])) { $options['host'] = '127.0.0.1'; } if (!isset($options['port'])) { $options['port'] = 11211; } if (!isset($options['persistent'])) { $options['persistent'] = false; } if (!isset($options['lifetime'])) { $options['lifetime'] = null; } $this->_prefix = isset($options['prefix']) ? $options['prefix'] : ''; $this->_options = $options; }
|
继承 SessionHandlerInterface 的类需要实现几个方法:open、close、read、write、destory 和 gc。
在 open 中连接 Memcached。
public function open($path, $name) { $options = $this->_options; if ($options) { $this->_memcached = new \Memcached($options); $this->_memcached->addServer($options['host'], $options['port'], $options['persistent']); return true; } return false; }
public function close() { return true; }
public function read($id) { return $this->_memcached->get($this->_prefix . $id, $this->_lifetime); }
public function write($id, $data) { return $this->_memcached->set($this->_prefix . $id, $data, $this->_lifetime); }
public function destroy($id) { if (!$id && $this->_memcached->exists($this->_prefix . $id)) { return $this->_memcached->delete($this->_prefix . $id); } return true; }
public function gc($maxlifetime) { return true; }
|
Handler 类写完之后,实例化它,并调用 session_set_save_handler 完成注册。
$options = []; $handler = new MemcachedHanlder($options); session_set_save_handler($handler, true);
|
这时候,开始畅享 SESSION 吧。
完整代码
class MemcachedHanlder implements SessionHandlerInterface { protected $_options; protected $_memcached; protected $_prefix;
function __construct(array $options = []) { if (!isset($options['host'])) { $options['host'] = '127.0.0.1'; } if (!isset($options['port'])) { $options['port'] = 11211; } if (!isset($options['persistent'])) { $options['persistent'] = false; } if (!isset($options['lifetime'])) { $options['lifetime'] = null; } $this->_prefix = isset($options['prefix']) ? $options['prefix'] : ''; $this->_options = $options; }
public function open($path, $name) { $options = $this->_options; if ($options) { $this->_memcached = new \Memcached($options); $this->_memcached->addServer($options['host'], $options['port'], $options['persistent']); return true; } return false; }
public function close() { return true; }
public function read($id) { return $this->_memcached->get($this->_prefix . $id, $this->_lifetime); }
public function write($id, $data) { return $this->_memcached->set($this->_prefix . $id, $data, $this->_lifetime); }
public function destroy($id) { if (!$id && $this->_memcached->exists($this->_prefix . $id)) { return $this->_memcached->delete($this->_prefix . $id); } return true; }
public function gc($maxlifetime) { return true; } } $options = []; $handler = new MemcachedHanlder($options); session_set_save_handler($handler, true);
|
总结
记得之前面试的时候,有人问过我 SESSION 与 COOKIE 之间的关系,SESSION 是怎么实现的,SESSION 除了存文件之外,还能够存在哪里,如何实现。
当初的我都没有回答上,想象当初真的是太年轻了,也很天真。越接触,越发现自己的渺小,越要勇往直前。
本文章观点仅代表个人立场,部分观点可能已过时,仅供参考。
本博客所有文章除特别声明外,均采用
CC BY-SA 4.0 协议,转载请注明出处!