AloFramework documentation
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Todo
  • Download

Namespaces

  • Alo
    • Cache
    • CLI
    • Controller
    • Db
    • Exception
    • FileSystem
    • Session
    • Statics
    • Test
    • Validators
    • Windows
  • Controller
  • None
  • PHP

Classes

  • AbstractCache
  • MemcachedWrapper
  • RedisWrapper
  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     * A wrapper for PHP's Memcached extension. Will try to use the Memcached class
 17     * first, if it doesn't exist, will use Memcache.
 18     *
 19     * @author  Art <a.molcanovas@gmail.com>
 20     * @package Cache
 21     */
 22    class MemcachedWrapper extends AbstractCache {
 23 
 24       /**
 25        * Defines the class as Memcached
 26        *
 27        * @var int
 28        */
 29       const CLASS_MEMCACHED = 1;
 30 
 31       /**
 32        * Defines the class as Memcache
 33        *
 34        * @var int
 35        */
 36       const CLASS_MEMCACHE = 2;
 37       /**
 38        * Whether the relevant cache extension is loaded
 39        *
 40        * @var boolean
 41        */
 42       protected static $loaded = null;
 43       /**
 44        * The memcached instance
 45        *
 46        * @var Memcache|Memcached
 47        */
 48       protected $client;
 49 
 50       /**
 51        * Instantiates the class
 52        *
 53        * @author Art <a.molcanovas@gmail.com>
 54        *
 55        * @param boolean $initialise_default_server Whether to add a server on construct
 56        */
 57       function __construct($initialise_default_server = true) {
 58          if(self::$loaded === null) {
 59             if(class_exists('\Memcached', false)) {
 60                self::$loaded = self::CLASS_MEMCACHED;
 61             } elseif(class_exists('\Memcache')) {
 62                self::$loaded = self::CLASS_MEMCACHE;
 63             } else {
 64                self::$loaded = false;
 65             }
 66          }
 67 
 68          if(self::$loaded !== null) {
 69             $this->client = self::$loaded === self::CLASS_MEMCACHED ? new Memcached() : new Memcache();
 70             if($initialise_default_server) {
 71                $this->addServer();
 72             }
 73          } else {
 74             trigger_error('Memcached extension not loaded - caching '
 75                           . 'functions will not work',
 76                           E_USER_NOTICE);
 77          }
 78          parent::__construct();
 79 
 80          \Log::debug(self::$loaded ? 'Loaded MemcachedWrapper' : 'MemcachedWrapper not loaded: extension unavailable');
 81       }
 82 
 83       /**
 84        * Adds a server to the pool
 85        *
 86        * @author Art <a.molcanovas@gmail.com>
 87        *
 88        * @param string $ip     The server IP
 89        * @param int    $port   The server port
 90        * @param int    $weight The server's weight, ie how likely it is to be used
 91        *
 92        * @return boolean
 93        */
 94       function addServer($ip = ALO_MEMCACHED_IP, $port = ALO_MEMCACHED_PORT, $weight = 1) {
 95          \Log::debug('Added MemcachedWrapper server ' . $ip . ':' . $port
 96                      . ' with a weight of ' . $weight);
 97 
 98          if(self::$loaded === self::CLASS_MEMCACHED) {
 99             return $this->client->addServer($ip, $port, $weight);
100          } elseif(self::$loaded === self::CLASS_MEMCACHE) {
101             return $this->client->addserver($ip, $port, null, $weight);
102          } else {
103             return false;
104          }
105       }
106 
107       /**
108        * Deletes a memcache key
109        *
110        * @author Art <a.molcanovas@gmail.com>
111        *
112        * @param string $key The key
113        *
114        * @return boolean
115        */
116       function delete($key) {
117          return self::$loaded ? $this->client->delete($key) : false;
118       }
119 
120       /**
121        * Instantiates the class
122        *
123        * @author Art <a.molcanovas@gmail.com>
124        *
125        * @param boolean $initialise_default_server Whether to add a server on construct
126        *
127        * @return MemcachedWrapper
128        */
129       static function MemcachedWrapper($initialise_default_server = true) {
130          return new MemcachedWrapper($initialise_default_server);
131       }
132 
133       /**
134        * Returns the loaded cache class
135        *
136        * @author Art <a.molcanovas@gmail.com>
137        * @return string|null
138        */
139       function getLoadedClass() {
140          return self::$loaded ? get_class($this->client) : null;
141       }
142 
143       /**
144        * Gets cache process info
145        *
146        * @author Art <a.molcanovas@gmail.com>
147        * @return array
148        */
149       function getStats() {
150          return self::$loaded ? $this->client->getStats() : false;
151       }
152 
153       /**
154        * Checks if a Memcache or Memcached is available
155        *
156        * @author Art <a.molcanovas@gmail.com>
157        * @return boolean
158        */
159       static function is_available() {
160          return class_exists('\Memcached') || class_exists('\Memcache');
161       }
162 
163       /**
164        * Clears all items from cache
165        *
166        * @author Art <a.molcanovas@gmail.com>
167        * @return boolean
168        */
169       function purge() {
170          return self::$loaded ? $this->client->flush() : false;
171       }
172 
173       /**
174        * Gets a cached value
175        *
176        * @author Art <a.molcanovas@gmail.com>
177        *
178        * @param string $id The value's key
179        *
180        * @return mixed
181        */
182       function get($id) {
183          return self::$loaded ? $this->client->get($id) : false;
184       }
185 
186       /**
187        * Sets a cached key/value pair
188        *
189        * @author Art <a.molcanovas@gmail.com>
190        *
191        * @param string $key    The key identifier
192        * @param mixed  $var    The value to set
193        * @param int    $expire When to expire the set data. Defaults to 3600s.
194        *
195        * @return boolean
196        */
197       function set($key, $var, $expire = 3600) {
198          \Log::debug('Set the MemcachedWrapper key ' . $key);
199 
200          if(self::$loaded === self::CLASS_MEMCACHED) {
201             return $this->client->set($key, $var, $expire);
202          } elseif(self::$loaded === self::CLASS_MEMCACHE) {
203             return $this->client->set($key, $var, null, $expire);
204          } else {
205             return false;
206          }
207       }
208 
209       /**
210        * The memcached version of getAll()
211        *
212        * @author Art <a.molcanovas@gmail.com>
213        * @return array
214        */
215       protected function getAllMemcached() {
216          $keys = $this->client->getAllKeys();
217          $vals = [];
218 
219          foreach($keys as $k) {
220             $vals[$k] = $this->get($k);
221          }
222 
223          return $vals;
224       }
225 
226       /**
227        * The Memcache version of getAll()
228        *
229        * @author Art <a.molcanovas@gmail.com>
230        * @return array
231        */
232       protected function getAllMemcache() {
233          $dump  = [];
234          $slabs = $this->client->getextendedstats('slabs');
235 
236          foreach($slabs as $serverSlabs) {
237             $keys = array_keys($serverSlabs);
238 
239             foreach($keys as $k) {
240                if(is_numeric($k)) {
241                   try {
242                      $d = $this->client->getextendedstats('cachedump', (int)$k, 1000);
243 
244                      foreach($d as $data) {
245                         if($data) {
246                            foreach($data as $mc_key => $row) {
247                               $dump[$mc_key] = $row[0];
248                            }
249                         }
250                      }
251                   } catch(\Exception $e) {
252                      continue;
253                   }
254                }
255             }
256          }
257 
258          return $dump;
259       }
260 
261       /**
262        * Return all cached keys and values
263        *
264        * @author Art <a.molcanovas@gmail.com>
265        * @return array
266        */
267       function getAll() {
268          if(self::$loaded === self::CLASS_MEMCACHED) {
269             return $this->getAllMemcached();
270          } elseif(self::$loaded === self::CLASS_MEMCACHE) {
271             return $this->getAllMemcache();
272          } else {
273             return [];
274          }
275       }
276 
277    }
AloFramework documentation API documentation generated by ApiGen 2.8.0