Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
 
3
/*
4
 * This file is part of the symfony package.
5
 * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
 
11
/**
12
 * Cache class that stores cached content in memcache.
13
 *
14
 * @package    symfony
15
 * @subpackage cache
16
 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17
 * @version    SVN: $Id: sfMemcacheCache.class.php 29490 2010-05-17 13:09:00Z fabien $
18
 */
19
class sfMemcacheCache extends sfCache
20
{
21
  protected
22
    $memcache = null;
23
 
24
  /**
25
   * Initializes this sfCache instance.
26
   *
27
   * Available options:
28
   *
29
   * * memcache: A memcache object (optional)
30
   *
31
   * * host:       The default host (default to localhost)
32
   * * port:       The port for the default server (default to 11211)
33
   * * persistent: true if the connection must be persistent, false otherwise (true by default)
34
   *
35
   * * servers:    An array of additional servers (keys: host, port, persistent)
36
   *
37
   * * see sfCache for options available for all drivers
38
   *
39
   * @see sfCache
40
   */
41
  public function initialize($options = array())
42
  {
43
    parent::initialize($options);
44
 
45
    if (!class_exists('Memcache'))
46
    {
47
      throw new sfInitializationException('You must have memcache installed and enabled to use sfMemcacheCache class.');
48
    }
49
 
50
    if ($this->getOption('memcache'))
51
    {
52
      $this->memcache = $this->getOption('memcache');
53
    }
54
    else
55
    {
56
      $this->memcache = new Memcache();
57
 
58
      if ($this->getOption('servers'))
59
      {
60
        foreach ($this->getOption('servers') as $server)
61
        {
62
          $port = isset($server['port']) ? $server['port'] : 11211;
63
          if (!$this->memcache->addServer($server['host'], $port, isset($server['persistent']) ? $server['persistent'] : true))
64
          {
65
            throw new sfInitializationException(sprintf('Unable to connect to the memcache server (%s:%s).', $server['host'], $port));
66
          }
67
        }
68
      }
69
      else
70
      {
71
        $method = $this->getOption('persistent', true) ? 'pconnect' : 'connect';
72
        if (!$this->memcache->$method($this->getOption('host', 'localhost'), $this->getOption('port', 11211), $this->getOption('timeout', 1)))
73
        {
74
          throw new sfInitializationException(sprintf('Unable to connect to the memcache server (%s:%s).', $this->getOption('host', 'localhost'), $this->getOption('port', 11211)));
75
        }
76
      }
77
    }
78
  }
79
 
80
  /**
81
   * @see sfCache
82
   */
83
  public function getBackend()
84
  {
85
    return $this->memcache;
86
  }
87
 
88
 /**
89
  * @see sfCache
90
  */
91
  public function get($key, $default = null)
92
  {
93
    $value = $this->memcache->get($this->getOption('prefix').$key);
94
 
95
    return false === $value ? $default : $value;
96
  }
97
 
98
  /**
99
   * @see sfCache
100
   */
101
  public function has($key)
102
  {
103
    return !(false === $this->memcache->get($this->getOption('prefix').$key));
104
  }
105
 
106
  /**
107
   * @see sfCache
108
   */
109
  public function set($key, $data, $lifetime = null)
110
  {
111
    $lifetime = null === $lifetime ? $this->getOption('lifetime') : $lifetime;
112
 
113
    // save metadata
114
    $this->setMetadata($key, $lifetime);
115
 
116
    // save key for removePattern()
117
    if ($this->getOption('storeCacheInfo', false))
118
    {
119
      $this->setCacheInfo($key);
120
    }
121
 
122
    if (false !== $this->memcache->replace($this->getOption('prefix').$key, $data, false, time() + $lifetime))
123
    {
124
      return true;
125
    }
126
 
127
    return $this->memcache->set($this->getOption('prefix').$key, $data, false, time() + $lifetime);
128
  }
129
 
130
  /**
131
   * @see sfCache
132
   */
133
  public function remove($key)
134
  {
135
    // delete metadata
136
    $this->memcache->delete($this->getOption('prefix').'_metadata'.self::SEPARATOR.$key, 0);
137
    if ($this->getOption('storeCacheInfo', false))
138
    {
139
      $this->setCacheInfo($key, true);
140
    }
141
    return $this->memcache->delete($this->getOption('prefix').$key, 0);
142
  }
143
 
144
  /**
145
   * @see sfCache
146
   */
147
  public function clean($mode = sfCache::ALL)
148
  {
149
    if (sfCache::ALL === $mode)
150
    {
151
      return $this->memcache->flush();
152
    }
153
  }
154
 
155
  /**
156
   * @see sfCache
157
   */
158
  public function getLastModified($key)
159
  {
160
    if (false === ($retval = $this->getMetadata($key)))
161
    {
162
      return 0;
163
    }
164
 
165
    return $retval['lastModified'];
166
  }
167
 
168
  /**
169
   * @see sfCache
170
   */
171
  public function getTimeout($key)
172
  {
173
    if (false === ($retval = $this->getMetadata($key)))
174
    {
175
      return 0;
176
    }
177
 
178
    return $retval['timeout'];
179
  }
180
 
181
  /**
182
   * @see sfCache
183
   */
184
  public function removePattern($pattern)
185
  {
186
    if (!$this->getOption('storeCacheInfo', false))
187
    {
188
      throw new sfCacheException('To use the "removePattern" method, you must set the "storeCacheInfo" option to "true".');
189
    }
190
 
191
    $regexp = self::patternToRegexp($this->getOption('prefix').$pattern);
192
    foreach ($this->getCacheInfo() as $key)
193
    {
194
      if (preg_match($regexp, $key))
195
      {
196
        $this->remove(substr($key, strlen($this->getOption('prefix'))));
197
      }
198
    }
199
  }
200
 
201
  /**
202
   * @see sfCache
203
   */
204
  public function getMany($keys)
205
  {
206
    $values = array();
207
    foreach ($this->memcache->get(array_map(create_function('$k', 'return "'.$this->getOption('prefix').'".$k;'), $keys)) as $key => $value)
208
    {
209
      $values[str_replace($this->getOption('prefix'), '', $key)] = $value;
210
    }
211
 
212
    return $values;
213
  }
214
 
215
  /**
216
   * Gets metadata about a key in the cache.
217
   *
218
   * @param string $key A cache key
219
   *
220
   * @return array An array of metadata information
221
   */
222
  protected function getMetadata($key)
223
  {
224
    return $this->memcache->get($this->getOption('prefix').'_metadata'.self::SEPARATOR.$key);
225
  }
226
 
227
  /**
228
   * Stores metadata about a key in the cache.
229
   *
230
   * @param string $key      A cache key
231
   * @param string $lifetime The lifetime
232
   */
233
  protected function setMetadata($key, $lifetime)
234
  {
235
    $this->memcache->set($this->getOption('prefix').'_metadata'.self::SEPARATOR.$key, array('lastModified' => time(), 'timeout' => time() + $lifetime), false, $lifetime);
236
  }
237
 
238
  /**
239
   * Updates the cache information for the given cache key.
240
   *
241
   * @param string $key The cache key
242
   * @param boolean $delete Delete key or not
243
   */
244
  protected function setCacheInfo($key, $delete = false)
245
  {
246
    $keys = $this->memcache->get($this->getOption('prefix').'_metadata');
247
    if (!is_array($keys))
248
    {
249
      $keys = array();
250
    }
251
 
252
    if ($delete)
253
    {
254
       if (($k = array_search($this->getOption('prefix').$key, $keys)) !== false)
255
       {
256
         unset($keys[$k]);
257
       }
258
    }
259
    else
260
    {
261
      if (!in_array($this->getOption('prefix').$key, $keys))
262
      {
263
        $keys[] = $this->getOption('prefix').$key;
264
      }
265
    }
266
 
267
    $this->memcache->set($this->getOption('prefix').'_metadata', $keys, 0);
268
  }
269
 
270
  /**
271
   * Gets cache information.
272
   */
273
  protected function getCacheInfo()
274
  {
275
    $keys = $this->memcache->get($this->getOption('prefix').'_metadata');
276
    if (!is_array($keys))
277
    {
278
      return array();
279
    }
280
 
281
    return $keys;
282
  }
283
}