1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20:
21: class NMemcachedStorage extends NObject implements ICacheStorage
22: {
23:
24: const META_CALLBACKS = 'callbacks';
25: const META_DATA = 'data';
26: const META_DELTA = 'delta';
27:
28:
29:
30: private $memcache;
31:
32:
33: private $prefix;
34:
35:
36:
37: 38: 39: 40:
41: public static function isAvailable()
42: {
43: return extension_loaded('memcache');
44: }
45:
46:
47:
48: public function __construct($host = 'localhost', $port = 11211, $prefix = '')
49: {
50: if (!self::isAvailable()) {
51: throw new Exception("PHP extension 'memcache' is not loaded.");
52: }
53:
54: $this->prefix = $prefix;
55: $this->memcache = new Memcache;
56: $this->memcache->connect($host, $port);
57: }
58:
59:
60:
61: 62: 63: 64: 65:
66: public function read($key)
67: {
68: $key = $this->prefix . $key;
69: $meta = $this->memcache->get($key);
70: if (!$meta) return NULL;
71:
72:
73:
74:
75:
76:
77:
78:
79:
80: if (!empty($meta[self::META_CALLBACKS]) && !NCache::checkCallbacks($meta[self::META_CALLBACKS])) {
81: $this->memcache->delete($key, 0);
82: return NULL;
83: }
84:
85: if (!empty($meta[self::META_DELTA])) {
86: $this->memcache->replace($key, $meta, 0, $meta[self::META_DELTA] + time());
87: }
88:
89: return $meta[self::META_DATA];
90: }
91:
92:
93:
94: 95: 96: 97: 98: 99: 100:
101: public function write($key, $data, array $dp)
102: {
103: if (!empty($dp[NCache::TAGS]) || isset($dp[NCache::PRIORITY]) || !empty($dp[NCache::ITEMS])) {
104: throw new NotSupportedException('Tags, priority and dependent items are not supported by MemcachedStorage.');
105: }
106:
107: $meta = array(
108: self::META_DATA => $data,
109: );
110:
111: $expire = 0;
112: if (isset($dp[NCache::EXPIRATION])) {
113: $expire = (int) $dp[NCache::EXPIRATION];
114: if (!empty($dp[NCache::SLIDING])) {
115: $meta[self::META_DELTA] = $expire;
116: }
117: }
118:
119: if (isset($dp[NCache::CALLBACKS])) {
120: $meta[self::META_CALLBACKS] = $dp[NCache::CALLBACKS];
121: }
122:
123: $this->memcache->set($this->prefix . $key, $meta, 0, $expire);
124: }
125:
126:
127:
128: 129: 130: 131: 132:
133: public function remove($key)
134: {
135: $this->memcache->delete($this->prefix . $key, 0);
136: }
137:
138:
139:
140: 141: 142: 143: 144:
145: public function clean(array $conds)
146: {
147: if (!empty($conds[NCache::ALL])) {
148: $this->memcache->flush();
149:
150: } elseif (isset($conds[NCache::TAGS]) || isset($conds[NCache::PRIORITY])) {
151: throw new NotSupportedException('Tags and priority is not supported by MemcachedStorage.');
152: }
153: }
154:
155: }
156: