Cache_memcached.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. <?php
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP
  6. *
  7. * This content is released under the MIT License (MIT)
  8. *
  9. * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
  10. *
  11. * 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:
  17. *
  18. * 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
  31. * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
  32. * @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
  33. * @license https://opensource.org/licenses/MIT MIT License
  34. * @link https://codeigniter.com
  35. * @since Version 2.0
  36. * @filesource
  37. */
  38. defined('BASEPATH') OR exit('No direct script access allowed');
  39. /**
  40. * CodeIgniter Memcached Caching Class
  41. *
  42. * @package CodeIgniter
  43. * @subpackage Libraries
  44. * @category Core
  45. * @author EllisLab Dev Team
  46. * @link
  47. */
  48. class CI_Cache_memcached extends CI_Driver {
  49. /**
  50. * Holds the memcached object
  51. *
  52. * @var object
  53. */
  54. protected $_memcached;
  55. /**
  56. * Memcached configuration
  57. *
  58. * @var array
  59. */
  60. protected $_config = array(
  61. 'default' => array(
  62. 'host' => '127.0.0.1',
  63. 'port' => 11211,
  64. 'weight' => 1
  65. )
  66. );
  67. // ------------------------------------------------------------------------
  68. /**
  69. * Class constructor
  70. *
  71. * Setup Memcache(d)
  72. *
  73. * @return void
  74. */
  75. public function __construct()
  76. {
  77. // Try to load memcached server info from the config file.
  78. $CI =& get_instance();
  79. $defaults = $this->_config['default'];
  80. if ($CI->config->load('memcached', TRUE, TRUE))
  81. {
  82. $this->_config = $CI->config->config['memcached'];
  83. }
  84. if (class_exists('Memcached', FALSE))
  85. {
  86. $this->_memcached = new Memcached();
  87. }
  88. elseif (class_exists('Memcache', FALSE))
  89. {
  90. $this->_memcached = new Memcache();
  91. }
  92. else
  93. {
  94. log_message('error', 'Cache: Failed to create Memcache(d) object; extension not loaded?');
  95. return;
  96. }
  97. foreach ($this->_config as $cache_server)
  98. {
  99. isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host'];
  100. isset($cache_server['port']) OR $cache_server['port'] = $defaults['port'];
  101. isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight'];
  102. if ($this->_memcached instanceof Memcache)
  103. {
  104. // Third parameter is persistence and defaults to TRUE.
  105. $this->_memcached->addServer(
  106. $cache_server['hostname'],
  107. $cache_server['port'],
  108. TRUE,
  109. $cache_server['weight']
  110. );
  111. }
  112. elseif ($this->_memcached instanceof Memcached)
  113. {
  114. $this->_memcached->addServer(
  115. $cache_server['hostname'],
  116. $cache_server['port'],
  117. $cache_server['weight']
  118. );
  119. }
  120. }
  121. }
  122. // ------------------------------------------------------------------------
  123. /**
  124. * Fetch from cache
  125. *
  126. * @param string $id Cache ID
  127. * @return mixed Data on success, FALSE on failure
  128. */
  129. public function get($id)
  130. {
  131. $data = $this->_memcached->get($id);
  132. return is_array($data) ? $data[0] : $data;
  133. }
  134. // ------------------------------------------------------------------------
  135. /**
  136. * Save
  137. *
  138. * @param string $id Cache ID
  139. * @param mixed $data Data being cached
  140. * @param int $ttl Time to live
  141. * @param bool $raw Whether to store the raw value
  142. * @return bool TRUE on success, FALSE on failure
  143. */
  144. public function save($id, $data, $ttl = 60, $raw = FALSE)
  145. {
  146. if ($raw !== TRUE)
  147. {
  148. $data = array($data, time(), $ttl);
  149. }
  150. if ($this->_memcached instanceof Memcached)
  151. {
  152. return $this->_memcached->set($id, $data, $ttl);
  153. }
  154. elseif ($this->_memcached instanceof Memcache)
  155. {
  156. return $this->_memcached->set($id, $data, 0, $ttl);
  157. }
  158. return FALSE;
  159. }
  160. // ------------------------------------------------------------------------
  161. /**
  162. * Delete from Cache
  163. *
  164. * @param mixed $id key to be deleted.
  165. * @return bool true on success, false on failure
  166. */
  167. public function delete($id)
  168. {
  169. return $this->_memcached->delete($id);
  170. }
  171. // ------------------------------------------------------------------------
  172. /**
  173. * Increment a raw value
  174. *
  175. * @param string $id Cache ID
  176. * @param int $offset Step/value to add
  177. * @return mixed New value on success or FALSE on failure
  178. */
  179. public function increment($id, $offset = 1)
  180. {
  181. if (($result = $this->_memcached->increment($id, $offset)) === FALSE)
  182. {
  183. return $this->_memcached->add($id, $offset) ? $offset : FALSE;
  184. }
  185. return $result;
  186. }
  187. // ------------------------------------------------------------------------
  188. /**
  189. * Decrement a raw value
  190. *
  191. * @param string $id Cache ID
  192. * @param int $offset Step/value to reduce by
  193. * @return mixed New value on success or FALSE on failure
  194. */
  195. public function decrement($id, $offset = 1)
  196. {
  197. if (($result = $this->_memcached->decrement($id, $offset)) === FALSE)
  198. {
  199. return $this->_memcached->add($id, 0) ? 0 : FALSE;
  200. }
  201. return $result;
  202. }
  203. // ------------------------------------------------------------------------
  204. /**
  205. * Clean the Cache
  206. *
  207. * @return bool false on failure/true on success
  208. */
  209. public function clean()
  210. {
  211. return $this->_memcached->flush();
  212. }
  213. // ------------------------------------------------------------------------
  214. /**
  215. * Cache Info
  216. *
  217. * @return mixed array on success, false on failure
  218. */
  219. public function cache_info()
  220. {
  221. return $this->_memcached->getStats();
  222. }
  223. // ------------------------------------------------------------------------
  224. /**
  225. * Get Cache Metadata
  226. *
  227. * @param mixed $id key to get cache metadata on
  228. * @return mixed FALSE on failure, array on success.
  229. */
  230. public function get_metadata($id)
  231. {
  232. $stored = $this->_memcached->get($id);
  233. if (count($stored) !== 3)
  234. {
  235. return FALSE;
  236. }
  237. list($data, $time, $ttl) = $stored;
  238. return array(
  239. 'expire' => $time + $ttl,
  240. 'mtime' => $time,
  241. 'data' => $data
  242. );
  243. }
  244. // ------------------------------------------------------------------------
  245. /**
  246. * Is supported
  247. *
  248. * Returns FALSE if memcached is not supported on the system.
  249. * If it is, we setup the memcached object & return TRUE
  250. *
  251. * @return bool
  252. */
  253. public function is_supported()
  254. {
  255. return (extension_loaded('memcached') OR extension_loaded('memcache'));
  256. }
  257. // ------------------------------------------------------------------------
  258. /**
  259. * Class destructor
  260. *
  261. * Closes the connection to Memcache(d) if present.
  262. *
  263. * @return void
  264. */
  265. public function __destruct()
  266. {
  267. if ($this->_memcached instanceof Memcache)
  268. {
  269. $this->_memcached->close();
  270. }
  271. elseif ($this->_memcached instanceof Memcached && method_exists($this->_memcached, 'quit'))
  272. {
  273. $this->_memcached->quit();
  274. }
  275. }
  276. }