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 | 90 | ||||
-rw-r--r-- | system/libraries/Cache/drivers/index.html | 2 | ||||
-rw-r--r-- | system/libraries/Cache/index.html | 2 |
6 files changed, 300 insertions, 44 deletions
diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php index d0c4c8881..f3dfe25e4 100644 --- a/system/libraries/Cache/Cache.php +++ b/system/libraries/Cache/Cache.php @@ -56,6 +56,7 @@ class CI_Cache extends CI_Driver_Library { */ protected $valid_drivers = array( 'apc', + 'apcu', 'dummy', 'file', 'memcached', @@ -253,4 +254,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..01f80e79b --- /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 - 2019, 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 - 2019, British Columbia Institute of Technology (https://bcit.ca/) + * @license https://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 89002de4f..55963bb82 100644 --- a/system/libraries/Cache/drivers/Cache_memcached.php +++ b/system/libraries/Cache/drivers/Cache_memcached.php @@ -103,10 +103,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 e8dd9b3a3..22af592e7 100644 --- a/system/libraries/Cache/drivers/Cache_redis.php +++ b/system/libraries/Cache/drivers/Cache_redis.php @@ -56,11 +56,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 ); /** @@ -71,13 +71,6 @@ class CI_Cache_redis extends CI_Driver protected $_redis; /** - * An internal cache for storing keys of serialized values. - * - * @var array - */ - protected $_serialized = array(); - - /** * del()/delete() method name depending on phpRedis version * * @var string @@ -102,6 +95,7 @@ class CI_Cache_redis extends CI_Driver * if a Redis connection can't be established. * * @return void + * @throws RedisException * @see Redis::connect() */ public function __construct() @@ -139,30 +133,21 @@ class CI_Cache_redis extends CI_Driver $this->_redis = new Redis(); - try + // The following calls used to be wrapped in a try ... catch + // and just log an error, but that only causes more errors later. + if ( ! $this->_redis->connect($config['host'], ($config['host'][0] === '/' ? 0 : $config['port']), $config['timeout'])) { - 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) - { - log_message('error', 'Cache: Redis connection failed. Check your configuration.'); - } + log_message('error', 'Cache: Redis connection failed. Check your configuration.'); + } - if (isset($config['password']) && ! $this->_redis->auth($config['password'])) - { - log_message('error', 'Cache: Redis authentication failed.'); - } + if (isset($config['password']) && ! $this->_redis->auth($config['password'])) + { + log_message('error', 'Cache: Redis authentication failed.'); } - catch (RedisException $e) + + if (isset($config['database']) && $config['database'] > 0 && ! $this->_redis->select($config['database'])) { - log_message('error', 'Cache: Redis connection refused ('.$e->getMessage().')'); + log_message('error', 'Cache: Redis select database failed.'); } } @@ -176,14 +161,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 && $this->_redis->sIsMember('_ci_redis_serialized', $key)) { - 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; + } } // ------------------------------------------------------------------------ @@ -199,22 +200,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; } else { $this->_redis->{static::$_sRemove_name}('_ci_redis_serialized', $id); } - return $this->_redis->set($id, $data, $ttl); + return TRUE; } // ------------------------------------------------------------------------ diff --git a/system/libraries/Cache/drivers/index.html b/system/libraries/Cache/drivers/index.html index b702fbc39..bcb7cae34 100644 --- a/system/libraries/Cache/drivers/index.html +++ b/system/libraries/Cache/drivers/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> diff --git a/system/libraries/Cache/index.html b/system/libraries/Cache/index.html index b702fbc39..bcb7cae34 100644 --- a/system/libraries/Cache/index.html +++ b/system/libraries/Cache/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> |