blob: 7e67fc40f9c196e48a6bd486ba85a5f88126c27d [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 Andreev125ef472016-01-11 12:33:00 +02009 * Copyright (c) 2014 - 2016, 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
Andrey Andreev1924e872016-01-11 12:55:34 +020031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
Andrey Andreev125ef472016-01-11 12:33:00 +020032 * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/)
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020033 * @license http://opensource.org/licenses/MIT MIT License
Andrey Andreevbd202c92016-01-11 12:50:18 +020034 * @link https://codeigniter.com
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020035 * @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 Andreev1be89872016-03-11 18:12:57 +0200110 return;
Andrey Andreev9aade1c2015-06-22 13:19:45 +0300111 }
112
113 foreach ($this->_memcache_conf as $cache_server)
114 {
115 isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host'];
116 isset($cache_server['port']) OR $cache_server['port'] = $defaults['port'];
117 isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight'];
118
119 if (get_class($this->_memcached) === 'Memcache')
120 {
121 // Third parameter is persistance and defaults to TRUE.
122 $this->_memcached->addServer(
123 $cache_server['hostname'],
124 $cache_server['port'],
125 TRUE,
126 $cache_server['weight']
127 );
128 }
129 else
130 {
131 $this->_memcached->addServer(
132 $cache_server['hostname'],
133 $cache_server['port'],
134 $cache_server['weight']
135 );
136 }
137 }
138 }
139
140 // ------------------------------------------------------------------------
141
Greg Akerbde25d92010-12-21 09:31:21 -0600142 /**
143 * Fetch from cache
144 *
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200145 * @param string $id Cache ID
146 * @return mixed Data on success, FALSE on failure
Greg Aker151b7a92011-08-21 12:29:43 -0500147 */
Greg Akerbde25d92010-12-21 09:31:21 -0600148 public function get($id)
Greg Aker151b7a92011-08-21 12:29:43 -0500149 {
Greg Akerbde25d92010-12-21 09:31:21 -0600150 $data = $this->_memcached->get($id);
Greg Aker151b7a92011-08-21 12:29:43 -0500151
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200152 return is_array($data) ? $data[0] : $data;
Greg Akerbde25d92010-12-21 09:31:21 -0600153 }
154
155 // ------------------------------------------------------------------------
156
157 /**
158 * Save
159 *
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200160 * @param string $id Cache ID
161 * @param mixed $data Data being cached
162 * @param int $ttl Time to live
163 * @param bool $raw Whether to store the raw value
164 * @return bool TRUE on success, FALSE on failure
Greg Akerbde25d92010-12-21 09:31:21 -0600165 */
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200166 public function save($id, $data, $ttl = 60, $raw = FALSE)
Greg Akerbde25d92010-12-21 09:31:21 -0600167 {
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200168 if ($raw !== TRUE)
169 {
Andrey Andreevb2a0e702014-01-18 16:54:51 +0200170 $data = array($data, time(), $ttl);
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200171 }
172
Andrey Andreevb24b0332012-03-26 15:34:39 +0300173 if (get_class($this->_memcached) === 'Memcached')
Mark Huotba00e9f2011-09-23 08:20:29 -0400174 {
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200175 return $this->_memcached->set($id, $data, $ttl);
Mark Huotba00e9f2011-09-23 08:20:29 -0400176 }
Andrey Andreevb24b0332012-03-26 15:34:39 +0300177 elseif (get_class($this->_memcached) === 'Memcache')
Mark Huotba00e9f2011-09-23 08:20:29 -0400178 {
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200179 return $this->_memcached->set($id, $data, 0, $ttl);
Mark Huotba00e9f2011-09-23 08:20:29 -0400180 }
Andrey Andreev7d4ea072011-12-25 19:23:50 +0200181
Mark Huotba00e9f2011-09-23 08:20:29 -0400182 return FALSE;
Greg Akerbde25d92010-12-21 09:31:21 -0600183 }
184
185 // ------------------------------------------------------------------------
Greg Aker151b7a92011-08-21 12:29:43 -0500186
Greg Akerbde25d92010-12-21 09:31:21 -0600187 /**
188 * Delete from Cache
189 *
Andrey Andreevb24b0332012-03-26 15:34:39 +0300190 * @param mixed key to be deleted.
Andrey Andreev56454792012-05-17 14:32:19 +0300191 * @return bool true on success, false on failure
Greg Akerbde25d92010-12-21 09:31:21 -0600192 */
193 public function delete($id)
194 {
195 return $this->_memcached->delete($id);
196 }
197
198 // ------------------------------------------------------------------------
Greg Aker151b7a92011-08-21 12:29:43 -0500199
Greg Akerbde25d92010-12-21 09:31:21 -0600200 /**
Andrey Andreev43d7fa72014-01-09 17:29:45 +0200201 * Increment a raw value
202 *
203 * @param string $id Cache ID
204 * @param int $offset Step/value to add
205 * @return mixed New value on success or FALSE on failure
206 */
207 public function increment($id, $offset = 1)
208 {
209 return $this->_memcached->increment($id, $offset);
210 }
211
212 // ------------------------------------------------------------------------
213
214 /**
215 * Decrement a raw value
216 *
217 * @param string $id Cache ID
218 * @param int $offset Step/value to reduce by
219 * @return mixed New value on success or FALSE on failure
220 */
221 public function decrement($id, $offset = 1)
222 {
223 return $this->_memcached->decrement($id, $offset);
224 }
225
226 // ------------------------------------------------------------------------
227
228 /**
Greg Akerbde25d92010-12-21 09:31:21 -0600229 * Clean the Cache
230 *
Andrey Andreevb24b0332012-03-26 15:34:39 +0300231 * @return bool false on failure/true on success
Greg Akerbde25d92010-12-21 09:31:21 -0600232 */
233 public function clean()
234 {
235 return $this->_memcached->flush();
236 }
237
238 // ------------------------------------------------------------------------
239
240 /**
241 * Cache Info
242 *
Andrey Andreevb24b0332012-03-26 15:34:39 +0300243 * @return mixed array on success, false on failure
Greg Akerbde25d92010-12-21 09:31:21 -0600244 */
Andrey Andreevb24b0332012-03-26 15:34:39 +0300245 public function cache_info()
Greg Akerbde25d92010-12-21 09:31:21 -0600246 {
247 return $this->_memcached->getStats();
248 }
249
250 // ------------------------------------------------------------------------
Greg Aker151b7a92011-08-21 12:29:43 -0500251
Greg Akerbde25d92010-12-21 09:31:21 -0600252 /**
253 * Get Cache Metadata
254 *
Andrey Andreevb24b0332012-03-26 15:34:39 +0300255 * @param mixed key to get cache metadata on
256 * @return mixed FALSE on failure, array on success.
Greg Akerbde25d92010-12-21 09:31:21 -0600257 */
258 public function get_metadata($id)
259 {
260 $stored = $this->_memcached->get($id);
261
262 if (count($stored) !== 3)
263 {
264 return FALSE;
265 }
266
Greg Aker999e7472011-01-29 16:16:58 -0600267 list($data, $time, $ttl) = $stored;
Greg Akerbde25d92010-12-21 09:31:21 -0600268
269 return array(
270 'expire' => $time + $ttl,
271 'mtime' => $time,
272 'data' => $data
273 );
274 }
275
276 // ------------------------------------------------------------------------
277
278 /**
Greg Akerbde25d92010-12-21 09:31:21 -0600279 * Is supported
280 *
281 * Returns FALSE if memcached is not supported on the system.
282 * If it is, we setup the memcached object & return TRUE
Andrey Andreevb24b0332012-03-26 15:34:39 +0300283 *
284 * @return bool
Greg Akerbde25d92010-12-21 09:31:21 -0600285 */
286 public function is_supported()
287 {
Andrey Andreev24a4a6a2015-08-31 15:11:47 +0300288 return (extension_loaded('memcached') OR extension_loaded('memcache'));
Greg Akerbde25d92010-12-21 09:31:21 -0600289 }
Greg Akerbde25d92010-12-21 09:31:21 -0600290}