1 <?php
2
3 namespace Alo\Cache;
4
5 use Memcache;
6 use Memcached;
7
8 if (!defined('GEN_START')) {
9 http_response_code(404);
10 die();
11 }
12
13 \Alo::loadConfig('memcached');
14
15 16 17 18 19 20 21
22 class MemcachedWrapper extends AbstractCache {
23
24 25 26 27 28
29 const CLASS_MEMCACHED = 1;
30
31 32 33 34 35
36 const CLASS_MEMCACHE = 2;
37
38 39 40 41 42
43 protected $mc;
44
45 46 47 48 49
50 protected static $loaded = null;
51
52 53 54 55 56 57
58 function __construct($initialise_default_server = true) {
59 if (self::$loaded === null) {
60 if (class_exists('\Memcached', false)) {
61 self::$loaded = self::CLASS_MEMCACHED;
62 } elseif (class_exists('\Memcache')) {
63 self::$loaded = self::CLASS_MEMCACHE;
64 } else {
65 self::$loaded = false;
66 }
67 }
68
69 if (self::$loaded !== null) {
70 $this->mc = self::$loaded === self::CLASS_MEMCACHED ? new Memcached() : new Memcache();
71 if ($initialise_default_server) {
72 $this->addServer();
73 }
74 } else {
75 trigger_error('Memcached extension not loaded - caching '
76 . 'functions will not work', E_USER_NOTICE);
77 }
78 parent::__construct();
79
80 \Log::debug(self::$loaded ? 'Loaded MemcachedWrapper' : 'MemcachedWrapper not loaded: extension unavailable');
81 }
82
83 84 85 86 87 88
89 function getLoadedClass() {
90 return self::$loaded ? get_class($this->mc) : null;
91 }
92
93 function purge() {
94 return self::$loaded ? $this->mc->flush() : false;
95 }
96
97 function addServer($ip = ALO_MEMCACHED_IP, $port = ALO_MEMCACHED_PORT, $weight = 1) {
98 \Log::debug('Added MemcachedWrapper server ' . $ip . ':' . $port
99 . ' with a weight of ' . $weight);
100
101 if (self::$loaded === self::CLASS_MEMCACHED) {
102 return $this->mc->addServer($ip, $port, $weight);
103 } elseif (self::$loaded === self::CLASS_MEMCACHE) {
104 return $this->mc->addserver($ip, $port, null, $weight);
105 } else {
106 return false;
107 }
108 }
109
110 function getStats() {
111 return self::$loaded ? $this->mc->getStats() : false;
112 }
113
114 function delete($key) {
115 return self::$loaded ? $this->mc->delete($key) : false;
116 }
117
118 function get($id) {
119 return self::$loaded ? $this->mc->get($id) : false;
120 }
121
122 function set($key, $var, $expire = 3600) {
123 \Log::debug('Set the MemcachedWrapper key ' . $key);
124
125 if (self::$loaded === self::CLASS_MEMCACHED) {
126 return $this->mc->set($key, $var, $expire);
127 } elseif (self::$loaded === self::CLASS_MEMCACHE) {
128 return $this->mc->set($key, $var, null, $expire);
129 } else {
130 return false;
131 }
132 }
133
134 135 136 137 138 139
140 protected function getAllMemcached() {
141 $keys = $this->mc->getAllKeys();
142 $vals = [];
143
144 foreach ($keys as $k) {
145 $vals[$k] = $this->get($k);
146 }
147
148 return $vals;
149 }
150
151 152 153 154 155 156
157 protected function getAllMemcache() {
158 $dump = [];
159 $slabs = $this->mc->getextendedstats('slabs');
160
161 foreach ($slabs as $serverSlabs) {
162 $keys = array_keys($serverSlabs);
163
164 foreach ($keys as $k) {
165 if (is_numeric($k)) {
166 try {
167 $d = $this->mc->getextendedstats('cachedump', (int)$k, 1000);
168
169 foreach ($d as $data) {
170 if ($data) {
171 foreach ($data as $mc_key => $row) {
172 $dump[$mc_key] = $row[0];
173 }
174 }
175 }
176 } catch (\Exception $e) {
177 continue;
178 }
179 }
180 }
181 }
182
183 return $dump;
184 }
185
186 function getAll() {
187 if (self::$loaded === self::CLASS_MEMCACHED) {
188 return $this->getAllMemcached();
189 } elseif (self::$loaded === self::CLASS_MEMCACHE) {
190 return $this->getAllMemcache();
191 } else {
192 return [];
193 }
194 }
195
196 }