├── .gitignore ├── LICENSE ├── controllers └── example_memcached.php ├── README.md ├── config └── memcached.php └── libraries └── memcached_library.php /.gitignore: -------------------------------------------------------------------------------- 1 | *.tmproj -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) {{year}} {{fullname}} 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /controllers/example_memcached.php: -------------------------------------------------------------------------------- 1 | load->library('memcached_library'); 14 | 15 | // Lets try to get the key 16 | $results = $this->memcached_library->get('test'); 17 | 18 | // If the key does not exist it could mean the key was never set or expired 19 | if (!$results) { 20 | // Modify this Query to your liking! 21 | $query = $this->db->get('members', 7000); 22 | 23 | // Lets store the results 24 | $this->memcached_library->add('test', $query->result()); 25 | 26 | // Output a basic msg 27 | echo 'Alright! Stored some results from the Query... Refresh Your Browser'; 28 | } else { 29 | // Output 30 | var_dump($results); 31 | 32 | // Now let us delete the key for demonstration sake! 33 | $this->memcached_library->delete('test'); 34 | } 35 | } 36 | 37 | public function stats() 38 | { 39 | $this->load->library('memcached_library'); 40 | 41 | echo $this->memcached_library->getversion(); 42 | echo '
'; 43 | 44 | // We can use any of the following "reset, malloc, maps, cachedump, slabs, items, sizes" 45 | $p = $this->memcached_library->getstats('sizes'); 46 | 47 | var_dump($p); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Memcached Library for CodeIgniter 2 | 3 | ##Description 4 | 5 | This library is to help interface between a CodeIgniter based project and 1 or more Memcached Servers ( http://www.danga.com/memcached/ ). It can also be used as a standalone php class with a few tweaks (the data in config/memcached.php needs to be loaded into the $config variable in the constructor). 6 | 7 | ##Misc 8 | 9 | There has been an issue going on with some people installing (PECL) 'Memcache' and some 'Memcached'. This library can handle either one but **Memcached** is preferred! 10 | 11 | ##Included 12 | 13 | - Library 14 | - Config File 15 | - Controller Example 16 | 17 | ## License 18 | 19 | The MIT License 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in 29 | all copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 37 | THE SOFTWARE. 38 | -------------------------------------------------------------------------------- /config/memcached.php: -------------------------------------------------------------------------------- 1 | [ 13 | 14 | 'host' => 'localhost', 15 | 'port' => '11211', 16 | 'weight' => '1', 17 | 'persistent' => false, 18 | 19 | ], 20 | ]; 21 | 22 | // -------------------------------------------------------------------------- 23 | // Configuration 24 | // -------------------------------------------------------------------------- 25 | $memcached['config'] = [ 26 | 27 | 'engine' => 'Memcached', // Set which caching engine you are using. Acceptable values: Memcached or Memcache 28 | 'prefix' => '', // Prefixes every key value (useful for multi environment setups) 29 | 'compression' => false, // Default: FALSE or MEMCACHE_COMPRESSED Compression Method (Memcache only). 30 | 31 | // Not necessary if you already are using 'compression' 32 | 'auto_compress_tresh' => false, // Controls the minimum value length before attempting to compress automatically. 33 | 'auto_compress_savings' => 0.2, // Specifies the minimum amount of savings to actually store the value compressed. The supplied value must be between 0 and 1. 34 | 35 | 'expiration' => 3600, // Default content expiration value (in seconds) 36 | 'delete_expiration' => 0, // Default time between the delete command and the actual delete action occurs (in seconds) 37 | 38 | ]; 39 | 40 | $config['memcached'] = $memcached; 41 | 42 | /* End of file memcached.php */ 43 | /* Location: ./system/application/config/memcached.php */ 44 | -------------------------------------------------------------------------------- /libraries/memcached_library.php: -------------------------------------------------------------------------------- 1 | ci = &get_instance(); 17 | 18 | // Load the memcached library config 19 | $this->ci->load->config('memcached'); 20 | $this->config = $this->ci->config->item('memcached'); 21 | 22 | // Lets try to load Memcache or Memcached Class 23 | $this->client_type = class_exists($this->config['config']['engine']) ? $this->config['config']['engine'] : false; 24 | 25 | if ($this->client_type) { 26 | // Which one should be loaded 27 | switch ($this->client_type) { 28 | case 'Memcached': 29 | $this->m = new Memcached(); 30 | break; 31 | case 'Memcache': 32 | $this->m = new Memcache(); 33 | // Set Automatic Compression Settings 34 | if ($this->config['config']['auto_compress_tresh']) { 35 | $this->setcompressthreshold($this->config['config']['auto_compress_tresh'], $this->config['config']['auto_compress_savings']); 36 | } 37 | break; 38 | } 39 | log_message('debug', 'Memcached Library: '.$this->client_type.' Class Loaded'); 40 | 41 | $this->auto_connect(); 42 | } else { 43 | log_message('error', 'Memcached Library: Failed to load Memcached or Memcache Class'); 44 | } 45 | } 46 | 47 | /* 48 | +-------------------------------------+ 49 | Name: auto_connect 50 | Purpose: runs through all of the servers defined in 51 | the configuration and attempts to connect to each 52 | @param return : none 53 | +-------------------------------------+ 54 | */ 55 | 56 | private function auto_connect() 57 | { 58 | foreach ($this->config['servers'] as $key => $server) { 59 | if (!$this->add_server($server)) { 60 | $this->errors[] = "Memcached Library: Could not connect to the server named $key"; 61 | log_message('error', 'Memcached Library: Could not connect to the server named "'.$key.'"'); 62 | } else { 63 | log_message('debug', 'Memcached Library: Successfully connected to the server named "'.$key.'"'); 64 | } 65 | } 66 | } 67 | 68 | /* 69 | +-------------------------------------+ 70 | Name: add_server 71 | Purpose: 72 | @param return : TRUE or FALSE 73 | +-------------------------------------+ 74 | */ 75 | 76 | public function add_server($server) 77 | { 78 | extract($server); 79 | 80 | return $this->m->addServer($host, $port, $weight); 81 | } 82 | 83 | /* 84 | +-------------------------------------+ 85 | Name: add 86 | Purpose: add an item to the memcache server(s) 87 | @param return : TRUE or FALSE 88 | +-------------------------------------+ 89 | */ 90 | 91 | public function add($key = null, $value = null, $expiration = null) 92 | { 93 | if (is_null($expiration)) { 94 | $expiration = $this->config['config']['expiration']; 95 | } 96 | if (is_array($key)) { 97 | foreach ($key as $multi) { 98 | if (!isset($multi['expiration']) || $multi['expiration'] == '') { 99 | $multi['expiration'] = $this->config['config']['expiration']; 100 | } 101 | $this->add($this->key_name($multi['key']), $multi['value'], $multi['expiration']); 102 | } 103 | } else { 104 | switch ($this->client_type) { 105 | case 'Memcache': 106 | $add_status = $this->m->add($this->key_name($key), $value, $this->config['config']['compression'], $expiration); 107 | break; 108 | 109 | default: 110 | case 'Memcached': 111 | $add_status = $this->m->add($this->key_name($key), $value, $expiration); 112 | break; 113 | } 114 | 115 | return $add_status; 116 | } 117 | } 118 | 119 | /* 120 | +-------------------------------------+ 121 | Name: set 122 | Purpose: similar to the add() method but uses set 123 | @param return : TRUE or FALSE 124 | +-------------------------------------+ 125 | */ 126 | 127 | public function set($key = null, $value = null, $expiration = null) 128 | { 129 | if (is_null($expiration)) { 130 | $expiration = $this->config['config']['expiration']; 131 | } 132 | if (is_array($key)) { 133 | foreach ($key as $multi) { 134 | if (!isset($multi['expiration']) || $multi['expiration'] == '') { 135 | $multi['expiration'] = $this->config['config']['expiration']; 136 | } 137 | $this->set($this->key_name($multi['key']), $multi['value'], $multi['expiration']); 138 | } 139 | } else { 140 | switch ($this->client_type) { 141 | case 'Memcache': 142 | $add_status = $this->m->set($this->key_name($key), $value, $this->config['config']['compression'], $expiration); 143 | break; 144 | 145 | default: 146 | case 'Memcached': 147 | $add_status = $this->m->set($this->key_name($key), $value, $expiration); 148 | break; 149 | } 150 | 151 | return $add_status; 152 | } 153 | } 154 | 155 | /* 156 | +-------------------------------------+ 157 | Name: get 158 | Purpose: gets the data for a single key or an array of keys 159 | @param return : array of data or multi-dimensional array of data 160 | +-------------------------------------+ 161 | */ 162 | 163 | public function get($key = null) 164 | { 165 | if ($this->m) { 166 | if (is_null($key)) { 167 | $this->errors[] = 'The key value cannot be NULL'; 168 | 169 | return false; 170 | } 171 | 172 | if (is_array($key)) { 173 | foreach ($key as $n => $k) { 174 | $key[$n] = $this->key_name($k); 175 | } 176 | 177 | return $this->m->getMulti($key); 178 | } else { 179 | return $this->m->get($this->key_name($key)); 180 | } 181 | } 182 | 183 | return false; 184 | } 185 | 186 | /* 187 | +-------------------------------------+ 188 | Name: delete 189 | Purpose: deletes a single or multiple data elements from the memached servers 190 | @param return : none 191 | +-------------------------------------+ 192 | */ 193 | 194 | public function delete($key, $expiration = null) 195 | { 196 | if (is_null($key)) { 197 | $this->errors[] = 'The key value cannot be NULL'; 198 | 199 | return false; 200 | } 201 | 202 | if (is_null($expiration)) { 203 | $expiration = $this->config['config']['delete_expiration']; 204 | } 205 | 206 | if (is_array($key)) { 207 | foreach ($key as $multi) { 208 | $this->delete($multi, $expiration); 209 | } 210 | } else { 211 | return $this->m->delete($this->key_name($key), $expiration); 212 | } 213 | } 214 | 215 | /* 216 | +-------------------------------------+ 217 | Name: replace 218 | Purpose: replaces the value of a key that already exists 219 | @param return : none 220 | +-------------------------------------+ 221 | */ 222 | 223 | public function replace($key = null, $value = null, $expiration = null) 224 | { 225 | if (is_null($expiration)) { 226 | $expiration = $this->config['config']['expiration']; 227 | } 228 | if (is_array($key)) { 229 | foreach ($key as $multi) { 230 | if (!isset($multi['expiration']) || $multi['expiration'] == '') { 231 | $multi['expiration'] = $this->config['config']['expiration']; 232 | } 233 | $this->replace($multi['key'], $multi['value'], $multi['expiration']); 234 | } 235 | } else { 236 | switch ($this->client_type) { 237 | case 'Memcache': 238 | $replace_status = $this->m->replace($this->key_name($key), $value, $this->config['config']['compression'], $expiration); 239 | break; 240 | 241 | default: 242 | case 'Memcached': 243 | $replace_status = $this->m->replace($this->key_name($key), $value, $expiration); 244 | break; 245 | } 246 | 247 | return $replace_status; 248 | } 249 | } 250 | 251 | /* 252 | +-------------------------------------+ 253 | Name: increment 254 | Purpose: increments a value 255 | @param return : none 256 | +-------------------------------------+ 257 | */ 258 | 259 | public function increment($key = null, $by = 1) 260 | { 261 | return $this->m->increment($this->key_name($key), $by); 262 | } 263 | 264 | /* 265 | +-------------------------------------+ 266 | Name: decrement 267 | Purpose: decrements a value 268 | @param return : none 269 | +-------------------------------------+ 270 | */ 271 | 272 | public function decrement($key = null, $by = 1) 273 | { 274 | return $this->m->decrement($this->key_name($key), $by); 275 | } 276 | 277 | /* 278 | +-------------------------------------+ 279 | Name: flush 280 | Purpose: flushes all items from cache 281 | @param return : none 282 | +-------------------------------------+ 283 | */ 284 | 285 | public function flush() 286 | { 287 | return $this->m->flush(); 288 | } 289 | 290 | /* 291 | +-------------------------------------+ 292 | Name: getversion 293 | Purpose: Get Server Vesion Number 294 | @param Returns a string of server version number or FALSE on failure. 295 | +-------------------------------------+ 296 | */ 297 | 298 | public function getversion() 299 | { 300 | return $this->m->getVersion(); 301 | } 302 | 303 | /* 304 | +-------------------------------------+ 305 | Name: getstats 306 | Purpose: Get Server Stats 307 | Possible: "reset, malloc, maps, cachedump, slabs, items, sizes" 308 | @param returns an associative array with server's statistics. Array keys correspond to stats parameters and values to parameter's values. 309 | +-------------------------------------+ 310 | */ 311 | 312 | public function getstats($type = 'items') 313 | { 314 | switch ($this->client_type) { 315 | case 'Memcache': 316 | $stats = $this->m->getStats($type); 317 | break; 318 | 319 | default: 320 | case 'Memcached': 321 | $stats = $this->m->getStats(); 322 | break; 323 | } 324 | 325 | return $stats; 326 | } 327 | 328 | /* 329 | +-------------------------------------+ 330 | Name: setcompresstreshold 331 | Purpose: Set When Automatic compression should kick-in 332 | @param return TRUE/FALSE 333 | +-------------------------------------+ 334 | */ 335 | 336 | public function setcompressthreshold($tresh, $savings = 0.2) 337 | { 338 | switch ($this->client_type) { 339 | case 'Memcache': 340 | $setcompressthreshold_status = $this->m->setCompressThreshold($tresh, $savings = 0.2); 341 | break; 342 | 343 | default: 344 | $setcompressthreshold_status = true; 345 | break; 346 | } 347 | 348 | return $setcompressthreshold_status; 349 | } 350 | 351 | /* 352 | +-------------------------------------+ 353 | Name: key_name 354 | Purpose: standardizes the key names for memcache instances 355 | @param return : md5 key name 356 | +-------------------------------------+ 357 | */ 358 | 359 | private function key_name($key) 360 | { 361 | return md5(strtolower($this->config['config']['prefix'].$key)); 362 | } 363 | 364 | /* 365 | +--------------------------------------+ 366 | Name: isConected 367 | Purpose: Check if the memcache server is connected. 368 | +--------------------------------------+ 369 | */ 370 | 371 | public function isConnected() 372 | { 373 | foreach ($this->getstats() as $key => $server) { 374 | if ($server['pid'] == -1) { 375 | return false; 376 | } 377 | 378 | return true; 379 | } 380 | } 381 | } 382 | --------------------------------------------------------------------------------