<?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('\Predis\Client')) { $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 \Predis\Client($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; } }