blob: 59cf4685db1287d78dc63adc0783f896c005e0fb [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Greg Akerbde25d92010-12-21 09:31:21 -06002/**
3 * CodeIgniter
4 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02005 * An open source application development framework for PHP
Derek Jonesf4a4bd82011-10-20 12:18:42 -05006 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +02007 * This content is released under the MIT License (MIT)
Andrey Andreev7d4ea072011-12-25 19:23:50 +02008 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02009 * Copyright (c) 2014 - 2015, British Columbia Institute of Technology
Andrey Andreev7d4ea072011-12-25 19:23:50 +020010 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020011 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
Greg Akerbde25d92010-12-21 09:31:21 -060017 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020018 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 * @package CodeIgniter
30 * @author EllisLab Dev Team
darwinel871754a2014-02-11 17:34:57 +010031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
Andrey Andreevfe9309d2015-01-09 17:48:58 +020032 * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020033 * @license http://opensource.org/licenses/MIT MIT License
34 * @link http://codeigniter.com
35 * @since Version 2.0
Greg Aker151b7a92011-08-21 12:29:43 -050036 * @filesource
Greg Akerbde25d92010-12-21 09:31:21 -060037 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020038defined('BASEPATH') OR exit('No direct script access allowed');
Greg Akerbde25d92010-12-21 09:31:21 -060039
Greg Akerbde25d92010-12-21 09:31:21 -060040/**
Greg Aker151b7a92011-08-21 12:29:43 -050041 * CodeIgniter Memcached Caching Class
Greg Akerbde25d92010-12-21 09:31:21 -060042 *
43 * @package CodeIgniter
44 * @subpackage Libraries
45 * @category Core
Derek Jonesf4a4bd82011-10-20 12:18:42 -050046 * @author EllisLab Dev Team
Greg Aker151b7a92011-08-21 12:29:43 -050047 * @link
Greg Akerbde25d92010-12-21 09:31:21 -060048 */
Phil Sturgeoneb2dcda2011-04-02 14:44:58 +010049class CI_Cache_memcached extends CI_Driver {
Greg Akerbde25d92010-12-21 09:31:21 -060050
Timothy Warren0688ac92012-04-20 10:25:04 -040051 /**
52 * Holds the memcached object
53 *
54 * @var object
55 */
56 protected $_memcached;
Greg Akerbde25d92010-12-21 09:31:21 -060057
Timothy Warren0688ac92012-04-20 10:25:04 -040058 /**
59 * Memcached configuration
60 *
61 * @var array
62 */
Andrey Andreev25df7a92014-07-31 13:42:07 +030063 protected $_memcache_conf = array(
Timothy Warren0688ac92012-04-20 10:25:04 -040064 'default' => array(
Andrey Andreev6a3d7e52013-07-18 19:14:05 +030065 'host' => '127.0.0.1',
66 'port' => 11211,
67 'weight' => 1
Timothy Warren0688ac92012-04-20 10:25:04 -040068 )
69 );
Greg Akerbde25d92010-12-21 09:31:21 -060070
Andrey Andreev9aade1c2015-06-22 13:19:45 +030071 // ------------------------------------------------------------------------
72
73 /**
74 * Class constructor
75 *
76 * Setup Memcache(d)
77 *
78 * @return void
79 */
80 public function __construct()
81 {
82 // Try to load memcached server info from the config file.
83 $CI =& get_instance();
84 $defaults = $this->_memcache_conf['default'];
85
86 if ($CI->config->load('memcached', TRUE, TRUE))
87 {
88 if (is_array($CI->config->config['memcached']))
89 {
90 $this->_memcache_conf = array();
91
92 foreach ($CI->config->config['memcached'] as $name => $conf)
93 {
94 $this->_memcache_conf[$name] = $conf;
95 }
96 }
97 }
98
99 if (class_exists('Memcached', FALSE))
100 {
101 $this->_memcached = new Memcached();
102 }
103 elseif (class_exists('Memcache', FALSE))
104 {
105 $this->_memcached = new Memcache();
106 }
107 else
108 {
Andrey Andreev24a4a6a2015-08-31 15:11:47 +0300109 log_message('error', 'Cache: Failed to create Memcache(d) object; extension not loaded?');
Andrey Andreev9aade1c2015-06-22 13:19:45 +0300110 }
111
112 foreach ($this->_memcache_conf as $cache_server)
113 {
114 isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host'];
115 isset($cache_server['port']) OR $cache_server['port'] = $defaults['port'];
116 isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight'];
117
118 if (get_class($this->_memcached) === 'Memcache')
119 {
120 // Third parameter is persistance and defaults to TRUE.
121 $this->_memcached->addServer(
122 $cache_server['hostname'],
123 $cache_server['port'],
124 TRUE,
125 $cache_server['weight']
126 );
127 }
128 else
129 {
130 $this->_memcached->addServer(
131 $cache_server['hostname'],
132 $cache_server['port'],
133 $cache_server['weight']
134 );
135 }
136 }
137 }
138
139 // ------------------------------------------------------------------------
140
Greg Akerbde25d92010-12-21 09:31:21 -0600141 /**
142 * Fetch from cache
143 *
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200144 * @param string $id Cache ID
145 * @return mixed Data on success, FALSE on failure
Greg Aker151b7a92011-08-21 12:29:43 -0500146 */
Greg Akerbde25d92010-12-21 09:31:21 -0600147 public function get($id)
Greg Aker151b7a92011-08-21 12:29:43 -0500148 {
Greg Akerbde25d92010-12-21 09:31:21 -0600149 $data = $this->_memcached->get($id);
Greg Aker151b7a92011-08-21 12:29:43 -0500150
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200151 return is_array($data) ? $data[0] : $data;
Greg Akerbde25d92010-12-21 09:31:21 -0600152 }
153
154 // ------------------------------------------------------------------------
155
156 /**
157 * Save
158 *
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200159 * @param string $id Cache ID
160 * @param mixed $data Data being cached
161 * @param int $ttl Time to live
162 * @param bool $raw Whether to store the raw value
163 * @return bool TRUE on success, FALSE on failure
Greg Akerbde25d92010-12-21 09:31:21 -0600164 */
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200165 public function save($id, $data, $ttl = 60, $raw = FALSE)
Greg Akerbde25d92010-12-21 09:31:21 -0600166 {
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200167 if ($raw !== TRUE)
168 {
Andrey Andreevb2a0e702014-01-18 16:54:51 +0200169 $data = array($data, time(), $ttl);
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200170 }
171
Andrey Andreevb24b0332012-03-26 15:34:39 +0300172 if (get_class($this->_memcached) === 'Memcached')
Mark Huotba00e9f2011-09-23 08:20:29 -0400173 {
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200174 return $this->_memcached->set($id, $data, $ttl);
Mark Huotba00e9f2011-09-23 08:20:29 -0400175 }
Andrey Andreevb24b0332012-03-26 15:34:39 +0300176 elseif (get_class($this->_memcached) === 'Memcache')
Mark Huotba00e9f2011-09-23 08:20:29 -0400177 {
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200178 return $this->_memcached->set($id, $data, 0, $ttl);
Mark Huotba00e9f2011-09-23 08:20:29 -0400179 }
Andrey Andreev7d4ea072011-12-25 19:23:50 +0200180
Mark Huotba00e9f2011-09-23 08:20:29 -0400181 return FALSE;
Greg Akerbde25d92010-12-21 09:31:21 -0600182 }
183
184 // ------------------------------------------------------------------------
Greg Aker151b7a92011-08-21 12:29:43 -0500185
Greg Akerbde25d92010-12-21 09:31:21 -0600186 /**
187 * Delete from Cache
188 *
Andrey Andreevb24b0332012-03-26 15:34:39 +0300189 * @param mixed key to be deleted.
Andrey Andreev56454792012-05-17 14:32:19 +0300190 * @return bool true on success, false on failure
Greg Akerbde25d92010-12-21 09:31:21 -0600191 */
192 public function delete($id)
193 {
194 return $this->_memcached->delete($id);
195 }
196
197 // ------------------------------------------------------------------------
Greg Aker151b7a92011-08-21 12:29:43 -0500198
Greg Akerbde25d92010-12-21 09:31:21 -0600199 /**
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200200 * Increment a raw value
201 *
202 * @param string $id Cache ID
203 * @param int $offset Step/value to add
204 * @return mixed New value on success or FALSE on failure
205 */
206 public function increment($id, $offset = 1)
207 {
208 return $this->_memcached->increment($id, $offset);
209 }
210
211 // ------------------------------------------------------------------------
212
213 /**
214 * Decrement a raw value
215 *
216 * @param string $id Cache ID
217 * @param int $offset Step/value to reduce by
218 * @return mixed New value on success or FALSE on failure
219 */
220 public function decrement($id, $offset = 1)
221 {
222 return $this->_memcached->decrement($id, $offset);
223 }
224
225 // ------------------------------------------------------------------------
226
227 /**
Greg Akerbde25d92010-12-21 09:31:21 -0600228 * Clean the Cache
229 *
Andrey Andreevb24b0332012-03-26 15:34:39 +0300230 * @return bool false on failure/true on success
Greg Akerbde25d92010-12-21 09:31:21 -0600231 */
232 public function clean()
233 {
234 return $this->_memcached->flush();
235 }
236
237 // ------------------------------------------------------------------------
238
239 /**
240 * Cache Info
241 *
Andrey Andreevb24b0332012-03-26 15:34:39 +0300242 * @return mixed array on success, false on failure
Greg Akerbde25d92010-12-21 09:31:21 -0600243 */
Andrey Andreevb24b0332012-03-26 15:34:39 +0300244 public function cache_info()
Greg Akerbde25d92010-12-21 09:31:21 -0600245 {
246 return $this->_memcached->getStats();
247 }
248
249 // ------------------------------------------------------------------------
Greg Aker151b7a92011-08-21 12:29:43 -0500250
Greg Akerbde25d92010-12-21 09:31:21 -0600251 /**
252 * Get Cache Metadata
253 *
Andrey Andreevb24b0332012-03-26 15:34:39 +0300254 * @param mixed key to get cache metadata on
255 * @return mixed FALSE on failure, array on success.
Greg Akerbde25d92010-12-21 09:31:21 -0600256 */
257 public function get_metadata($id)
258 {
259 $stored = $this->_memcached->get($id);
260
261 if (count($stored) !== 3)
262 {
263 return FALSE;
264 }
265
Greg Aker999e7472011-01-29 16:16:58 -0600266 list($data, $time, $ttl) = $stored;
Greg Akerbde25d92010-12-21 09:31:21 -0600267
268 return array(
269 'expire' => $time + $ttl,
270 'mtime' => $time,
271 'data' => $data
272 );
273 }
274
275 // ------------------------------------------------------------------------
276
277 /**
Greg Akerbde25d92010-12-21 09:31:21 -0600278 * Is supported
279 *
280 * Returns FALSE if memcached is not supported on the system.
281 * If it is, we setup the memcached object & return TRUE
Andrey Andreevb24b0332012-03-26 15:34:39 +0300282 *
283 * @return bool
Greg Akerbde25d92010-12-21 09:31:21 -0600284 */
285 public function is_supported()
286 {
Andrey Andreev24a4a6a2015-08-31 15:11:47 +0300287 return (extension_loaded('memcached') OR extension_loaded('memcache'));
Greg Akerbde25d92010-12-21 09:31:21 -0600288 }
Greg Akerbde25d92010-12-21 09:31:21 -0600289}