Zend Framework实现将session存储在memcache中的方法

时间:2022-08-22 19:42:52

本文实例讲述了Zend Framework实现将session存储在memcache中的方法。分享给大家供大家参考,具体如下:

在zend framework中,已经可以将session存储在数据库中了,不过还不支持memcache,我简单得实现了一下。

下面是SaveHandler,文件名为 :Memcached.php ,将其放在 /Zend/Session/SaveHandler 目录下,代码如下(需要有php_memcache支持,因为字符长度限制,我把部分注释去掉了):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
require_once 'Zend/Session.php';
require_once 'Zend/Config.php';
class Zend_Session_SaveHandler_Memcached implements Zend_Session_SaveHandler_Interface
{
  const LIFETIME     = 'lifetime';
  const OVERRIDE_LIFETIME = 'overrideLifetime';
  const MEMCACHED      = 'memcached';
  protected $_lifetime = false;
  protected $_overrideLifetime = false;
  protected $_sessionSavePath;
  protected $_sessionName;
  protected $_memcached;
  /**
   * Constructor
   *
   * $config is an instance of Zend_Config or an array of key/value pairs containing configuration options for
   * Zend_Session_SaveHandler_Memcached . These are the configuration options for
   * Zend_Session_SaveHandler_Memcached:
   *
   *
   *   sessionId    => The id of the current session
   *   sessionName   => The name of the current session
   *   sessionSavePath => The save path of the current session
   *
   * modified      => (string) Session last modification time column
   *
   * lifetime     => (integer) Session lifetime (optional; default: ini_get('session.gc_maxlifetime'))
   *
   * overrideLifetime => (boolean) Whether or not the lifetime of an existing session should be overridden
   *   (optional; default: false)
   *
   * @param Zend_Config|array $config   User-provided configuration
   * @return void
   * @throws Zend_Session_SaveHandler_Exception
   */
  public function __construct($config)
  {
    if ($config instanceof Zend_Config) {
      $config = $config->toArray();
    } else if (!is_array($config)) {
      /**
       * @see Zend_Session_SaveHandler_Exception
       */
      require_once 'Zend/Session/SaveHandler/Exception.php';
      throw new Zend_Session_SaveHandler_Exception(
        '$config must be an instance of Zend_Config or array of key/value pairs containing '
       . 'configuration options for Zend_Session_SaveHandler_Memcached .');
    }
    foreach ($config as $key => $value) {
      do {
        switch ($key) {
          case self::MEMCACHED:
            $this->createMemcached($value);
            break;
          case self::LIFETIME:
            $this->setLifetime($value);
            break;
          case self::OVERRIDE_LIFETIME:
            $this->setOverrideLifetime($value);
            break;
          default:
            // unrecognized options passed to parent::__construct()
            break 2;
        }
        unset($config[$key]);
      } while (false);
    }
  }
  /**
   * 创建memcached连接对象
   *
   * @return void
   */
  public function createMemcached($config){
   $mc = new Memcache;
   foreach ($config as $value){
    $mc->addServer($value['ip'], $value['port']);
   }
   $this->_memcached = $mc;
  }
  public function __destruct()
  {
    Zend_Session::writeClose();
  }
  /**
   * Set session lifetime and optional whether or not the lifetime of an existing session should be overridden
   *
   * $lifetime === false resets lifetime to session.gc_maxlifetime
   *
   * @param int $lifetime
   * @param boolean $overrideLifetime (optional)
   * @return Zend_Session_SaveHandler_Memcached
   */
  public function setLifetime($lifetime, $overrideLifetime = null)
  {
    if ($lifetime < 0) {
      /**
       * @see Zend_Session_SaveHandler_Exception
       */
      require_once 'Zend/Session/SaveHandler/Exception.php';
      throw new Zend_Session_SaveHandler_Exception();
    } else if (empty($lifetime)) {
      $this->_lifetime = (int) ini_get('session.gc_maxlifetime');
    } else {
      $this->_lifetime = (int) $lifetime;
    }
    if ($overrideLifetime != null) {
      $this->setOverrideLifetime($overrideLifetime);
    }
    return $this;
  }
  /**
   * Retrieve session lifetime
   *
   * @return int
   */
  public function getLifetime()
  {
    return $this->_lifetime;
  }
  /**
   * Set whether or not the lifetime of an existing session should be overridden
   *
   * @param boolean $overrideLifetime
   * @return Zend_Session_SaveHandler_Memcached
   */
  public function setOverrideLifetime($overrideLifetime)
  {
    $this->_overrideLifetime = (boolean) $overrideLifetime;
    return $this;
  }
  public function getOverrideLifetime()
  {
    return $this->_overrideLifetime;
  }
  /**
   * Retrieve session lifetime considering
   *
   * @param array $value
   * @return int
   */
  public function open($save_path, $name)
  {
    $this->_sessionSavePath = $save_path;
    $this->_sessionName   = $name;
    return true;
  }
  /**
   * Retrieve session expiration time
   *
   * @param * @param array $value
   * @return int
   */
  public function close()
  {
    return true;
  }
  public function read($id)
  {
    $return = '';
    $value = $this->_memcached->get($id); //获取数据
    if ($value) {
      if ($this->_getExpirationTime($value) > time()) {
        $return = $value['data'];
      } else {
        $this->destroy($id);
      }
    }
    return $return;
  }
  public function write($id, $data)
  {
    $return = false;
    $insertDate = array('modified' => time(),
               'data'   => (string) $data);
      $value = $this->_memcached->get($id); //获取数据
    if ($value) {
      $insertDate['lifetime'] = $this->_getLifetime($value);
      if ($this->_memcached->replace($id,$insertDate)) {
        $return = true;
      }
    } else {
      $insertDate['lifetime'] = $this->_lifetime;
      if ($this->_memcached->add($id, $insertDate,false,$this->_lifetime)) {
        $return = true;
      }
    }
    return $return;
  }
  public function destroy($id)
  {
    $return = false;
    if ($this->_memcached->delete($id)) {
      $return = true;
    }
    return $return;
  }
  public function gc($maxlifetime)
  {
    return true;
  }
  protected function _getLifetime($value)
  {
    $return = $this->_lifetime;
    if (!$this->_overrideLifetime) {
      $return = (int) $value['lifetime'];
    }
    return $return;
  }
  protected function _getExpirationTime($value)
  {
    return (int) $value['modified'] + $this->_getLifetime($value);
  }
}

配置(可以添加多台memcache服务器,做分布式):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$config = array(
  'memcached'=> array(
    array(
      'ip'=>'192.168.0.1',
      'port'=>11211
    )
  ),
  'lifetime' =>123334
);
//create your Zend_Session_SaveHandler_DbTable and
//set the save handler for Zend_Session
Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_Memcached($config));
//start your session!
Zend_Session::start();

配置好后,session的使用方法和以前一样,不用管底层是怎么实现的!

希望本文所述对大家基于Zend Framework框架的PHP程序设计有所帮助。