diff options
Diffstat (limited to 'system/libraries/Cache')
-rw-r--r-- | system/libraries/Cache/Cache.php | 13 | ||||
-rw-r--r-- | system/libraries/Cache/drivers/Cache_apcu.php | 219 | ||||
-rw-r--r-- | system/libraries/Cache/drivers/Cache_memcached.php | 18 | ||||
-rw-r--r-- | system/libraries/Cache/drivers/Cache_redis.php | 102 |
4 files changed, 298 insertions, 54 deletions
diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php index 267dffb09..1b1801b5a 100644 --- a/system/libraries/Cache/Cache.php +++ b/system/libraries/Cache/Cache.php @@ -55,6 +55,7 @@ class CI_Cache extends CI_Driver_Library { */ protected $valid_drivers = array( 'apc', + 'apcu', 'dummy', 'file', 'memcached', @@ -252,4 +253,16 @@ class CI_Cache extends CI_Driver_Library { return $support[$driver]; } + + // ------------------------------------------------------------------------ + + /** + * Get currently loaded driver + * + * @return string + */ + public function get_loaded_driver() + { + return $this->_adapter; + } } diff --git a/system/libraries/Cache/drivers/Cache_apcu.php b/system/libraries/Cache/drivers/Cache_apcu.php new file mode 100644 index 000000000..9b7fe877c --- /dev/null +++ b/system/libraries/Cache/drivers/Cache_apcu.php @@ -0,0 +1,219 @@ +<?php +/** + * CodeIgniter + * + * An open source application development framework for PHP + * + * This content is released under the MIT License (MIT) + * + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) + * @license http://opensource.org/licenses/MIT MIT License + * @link https://codeigniter.com + * @since Version 3.2.0 + * @filesource + */ +defined('BASEPATH') OR exit('No direct script access allowed'); + +/** + * CodeIgniter APCu Caching Class + * + * @package CodeIgniter + * @subpackage Libraries + * @category Core + * @author CodeIgniter Dev team + */ +class CI_Cache_apcu extends CI_Driver { + + /** + * Class constructor + * + * Only present so that an error message is logged + * if APCu is not available. + * + * @return void + */ + public function __construct() + { + if ( ! $this->is_supported()) + { + log_message('error', 'Cache: Failed to initialize APCu; extension not loaded/enabled?'); + } + } + + // ------------------------------------------------------------------------ + + /** + * Get + * + * Look for a value in the cache. If it exists, return the data + * if not, return FALSE + * + * @param string + * @return mixed value that is stored/FALSE on failure + */ + public function get($id) + { + $success = FALSE; + $data = apcu_fetch($id, $success); + + if ($success === TRUE) + { + return is_array($data) + ? $data[0] + : $data; + } + + return FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Cache Save + * + * @param string $id Cache ID + * @param mixed $data Data to store + * @param int $ttl Length of time (in seconds) to cache the data + * @param bool $raw Whether to store the raw value + * @return bool TRUE on success, FALSE on failure + */ + public function save($id, $data, $ttl = 60, $raw = FALSE) + { + $ttl = (int) $ttl; + + return apcu_store( + $id, + ($raw === TRUE ? $data : array($data, time(), $ttl)), + $ttl + ); + } + + // ------------------------------------------------------------------------ + + /** + * Delete from Cache + * + * @param mixed unique identifier of the item in the cache + * @return bool true on success/false on failure + */ + public function delete($id) + { + return apcu_delete($id); + } + + // ------------------------------------------------------------------------ + + /** + * Increment a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to add + * @return mixed New value on success or FALSE on failure + */ + public function increment($id, $offset = 1) + { + return apcu_inc($id, $offset); + } + + // ------------------------------------------------------------------------ + + /** + * Decrement a raw value + * + * @param string $id Cache ID + * @param int $offset Step/value to reduce by + * @return mixed New value on success or FALSE on failure + */ + public function decrement($id, $offset = 1) + { + return apcu_dec($id, $offset); + } + + // ------------------------------------------------------------------------ + + /** + * Clean the cache + * + * @return bool false on failure/true on success + */ + public function clean() + { + return apcu_clear_cache(); + } + + // ------------------------------------------------------------------------ + + /** + * Cache Info + * + * @return mixed array on success, false on failure + */ + public function cache_info() + { + return apcu_cache_info(); + } + + // ------------------------------------------------------------------------ + + /** + * Get Cache Metadata + * + * @param mixed key to get cache metadata on + * @return mixed array on success/false on failure + */ + public function get_metadata($id) + { + $success = FALSE; + $stored = apcu_fetch($id, $success); + + if ($success === FALSE OR count($stored) !== 3) + { + return FALSE; + } + + list($data, $time, $ttl) = $stored; + + return array( + 'expire' => $time + $ttl, + 'mtime' => $time, + 'data' => $data + ); + } + + // ------------------------------------------------------------------------ + + /** + * is_supported() + * + * Check to see if APCu is available on this system, bail if it isn't. + * + * @return bool + */ + public function is_supported() + { + return (extension_loaded('apcu') && ini_get('apc.enabled')); + } +}
\ No newline at end of file diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php index b642a2c03..4836b6aed 100644 --- a/system/libraries/Cache/drivers/Cache_memcached.php +++ b/system/libraries/Cache/drivers/Cache_memcached.php @@ -102,10 +102,22 @@ class CI_Cache_memcached extends CI_Driver { return; } - foreach ($this->_config as $cache_server) + foreach ($this->_config as $cache_name => $cache_server) { - isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host']; - isset($cache_server['port']) OR $cache_server['port'] = $defaults['port']; + if ( ! isset($cache_server['hostname'])) + { + log_message('debug', 'Cache: Memcache(d) configuration "'.$cache_name.'" doesn\'t include a hostname; ignoring.'); + continue; + } + elseif ($cache_server['hostname'][0] === '/') + { + $cache_server['port'] = 0; + } + elseif (empty($cache_server['port'])) + { + $cache_server['port'] = $defaults['port']; + } + isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight']; if ($this->_memcached instanceof Memcache) diff --git a/system/libraries/Cache/drivers/Cache_redis.php b/system/libraries/Cache/drivers/Cache_redis.php index ac67be077..bb26b3b47 100644 --- a/system/libraries/Cache/drivers/Cache_redis.php +++ b/system/libraries/Cache/drivers/Cache_redis.php @@ -55,11 +55,11 @@ class CI_Cache_redis extends CI_Driver * @var array */ protected static $_default_config = array( - 'socket_type' => 'tcp', 'host' => '127.0.0.1', 'password' => NULL, 'port' => 6379, - 'timeout' => 0 + 'timeout' => 0, + 'database' => 0 ); /** @@ -69,13 +69,6 @@ class CI_Cache_redis extends CI_Driver */ protected $_redis; - /** - * An internal cache for storing keys of serialized values. - * - * @var array - */ - protected $_serialized = array(); - // ------------------------------------------------------------------------ /** @@ -112,16 +105,7 @@ class CI_Cache_redis extends CI_Driver try { - if ($config['socket_type'] === 'unix') - { - $success = $this->_redis->connect($config['socket']); - } - else // tcp socket - { - $success = $this->_redis->connect($config['host'], $config['port'], $config['timeout']); - } - - if ( ! $success) + if ( ! $this->_redis->connect($config['host'], ($config['host'][0] === '/' ? 0 : $config['port']), $config['timeout'])) { log_message('error', 'Cache: Redis connection failed. Check your configuration.'); } @@ -130,15 +114,16 @@ class CI_Cache_redis extends CI_Driver { log_message('error', 'Cache: Redis authentication failed.'); } + + if (isset($config['database']) && $config['database'] > 0 && ! $this->_redis->select($config['database'])) + { + log_message('error', 'Cache: Redis select database failed.'); + } } catch (RedisException $e) { log_message('error', 'Cache: Redis connection refused ('.$e->getMessage().')'); } - - // Initialize the index of serialized values. - $serialized = $this->_redis->sMembers('_ci_redis_serialized'); - empty($serialized) OR $this->_serialized = array_flip($serialized); } // ------------------------------------------------------------------------ @@ -151,14 +136,30 @@ class CI_Cache_redis extends CI_Driver */ public function get($key) { - $value = $this->_redis->get($key); + $data = $this->_redis->hMGet($key, array('__ci_type', '__ci_value')); - if ($value !== FALSE && isset($this->_serialized[$key])) + if ( ! isset($data['__ci_type'], $data['__ci_value']) OR $data['__ci_value'] === FALSE) { - return unserialize($value); + return FALSE; } - return $value; + switch ($data['__ci_type']) + { + case 'array': + case 'object': + return unserialize($data['__ci_value']); + case 'boolean': + case 'integer': + case 'double': // Yes, 'double' is returned and NOT 'float' + case 'string': + case 'NULL': + return settype($data['__ci_value'], $data['__ci_type']) + ? $data['__ci_value'] + : FALSE; + case 'resource': + default: + return FALSE; + } } // ------------------------------------------------------------------------ @@ -174,23 +175,33 @@ class CI_Cache_redis extends CI_Driver */ public function save($id, $data, $ttl = 60, $raw = FALSE) { - if (is_array($data) OR is_object($data)) + switch ($data_type = gettype($data)) { - if ( ! $this->_redis->sIsMember('_ci_redis_serialized', $id) && ! $this->_redis->sAdd('_ci_redis_serialized', $id)) - { + case 'array': + case 'object': + $data = serialize($data); + break; + case 'boolean': + case 'integer': + case 'double': // Yes, 'double' is returned and NOT 'float' + case 'string': + case 'NULL': + break; + case 'resource': + default: return FALSE; - } + } - isset($this->_serialized[$id]) OR $this->_serialized[$id] = TRUE; - $data = serialize($data); + if ( ! $this->_redis->hMSet($id, array('__ci_type' => $data_type, '__ci_value' => $data))) + { + return FALSE; } - elseif (isset($this->_serialized[$id])) + elseif ($ttl) { - $this->_serialized[$id] = NULL; - $this->_redis->sRemove('_ci_redis_serialized', $id); + $this->_redis->expireAt($id, time() + $ttl); } - return $this->_redis->set($id, $data, $ttl); + return TRUE; } // ------------------------------------------------------------------------ @@ -203,18 +214,7 @@ class CI_Cache_redis extends CI_Driver */ public function delete($key) { - if ($this->_redis->delete($key) !== 1) - { - return FALSE; - } - - if (isset($this->_serialized[$key])) - { - $this->_serialized[$key] = NULL; - $this->_redis->sRemove('_ci_redis_serialized', $key); - } - - return TRUE; + return ($this->_redis->delete($key) === 1); } // ------------------------------------------------------------------------ @@ -228,7 +228,7 @@ class CI_Cache_redis extends CI_Driver */ public function increment($id, $offset = 1) { - return $this->_redis->incr($id, $offset); + return $this->_redis->hIncrBy($id, 'data', $offset); } // ------------------------------------------------------------------------ @@ -242,7 +242,7 @@ class CI_Cache_redis extends CI_Driver */ public function decrement($id, $offset = 1) { - return $this->_redis->decr($id, $offset); + return $this->_redis->hIncrBy($id, 'data', -$offset); } // ------------------------------------------------------------------------ |