123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- <?php
- /**
- * KO7 Cache provides a common interface to a variety of caching engines. Tags are
- * supported where available natively to the cache system. KO7 Cache supports multiple
- * instances of cache engines through a grouped singleton pattern.
- *
- * ### Supported cache engines
- *
- * * [APC](http://php.net/manual/en/book.apc.php)
- * * [eAccelerator](http://eaccelerator.net/)
- * * File
- * * [Memcache](http://memcached.org/)
- * * [Memcached-tags](http://code.google.com/p/memcached-tags/)
- * * [SQLite](http://www.sqlite.org/)
- * * [Xcache](http://xcache.lighttpd.net/)
- *
- * ### Introduction to caching
- *
- * Caching should be implemented with consideration. Generally, caching the result of resources
- * is faster than reprocessing them. Choosing what, how and when to cache is vital. PHP APC is
- * presently one of the fastest caching systems available, closely followed by Memcache. SQLite
- * and File caching are two of the slowest cache methods, however usually faster than reprocessing
- * a complex set of instructions.
- *
- * Caching engines that use memory are considerably faster than the file based alternatives. But
- * memory is limited whereas disk space is plentiful. If caching large datasets it is best to use
- * file caching.
- *
- * ### Configuration settings
- *
- * KO7 Cache uses configuration groups to create cache instances. A configuration group can
- * use any supported driver, with successive groups using the same driver type if required.
- *
- * #### Configuration example
- *
- * Below is an example of a _memcache_ server configuration.
- *
- * return array(
- * 'memcache' => array( // Name of group
- * 'driver' => 'memcache', // using Memcache driver
- * 'servers' => array( // Available server definitions
- * array(
- * 'host' => 'localhost',
- * 'port' => 11211,
- * 'persistent' => FALSE
- * )
- * ),
- * 'compression' => FALSE, // Use compression?
- * ),
- * )
- *
- * In cases where only one cache group is required, set `Cache::$default` (in your bootstrap,
- * or by extending `KO7_Cache` class) to the name of the group, and use:
- *
- * $cache = Cache::instance(); // instead of Cache::instance('memcache')
- *
- * It will return the cache instance of the group it has been set in `Cache::$default`.
- *
- * #### General cache group configuration settings
- *
- * Below are the settings available to all types of cache driver.
- *
- * Name | Required | Description
- * -------------- | -------- | ---------------------------------------------------------------
- * driver | __YES__ | (_string_) The driver type to use
- *
- * Details of the settings specific to each driver are available within the drivers documentation.
- *
- * ### System requirements
- *
- * * KO7 3.0.x
- * * PHP 5.2.4 or greater
- *
- * @package KO7/Cache
- * @category Base
- * @version 2.0
- *
- * @copyright (c) 2007-2016 Kohana Team
- * @copyright (c) since 2016 Koseven Team
- * @license https://koseven.dev/LICENSE
- */
- abstract class KO7_Cache {
- const DEFAULT_EXPIRE = 3600;
- /**
- * @var string default driver to use
- */
- public static $default = 'file';
- /**
- * @var KO7_Cache instances
- */
- public static $instances = [];
- /**
- * Creates a singleton of a KO7 Cache group. If no group is supplied
- * the __default__ cache group is used.
- *
- * // Create an instance of the default group
- * $default_group = Cache::instance();
- *
- * // Create an instance of a group
- * $foo_group = Cache::instance('foo');
- *
- * // Access an instantiated group directly
- * $foo_group = Cache::$instances['default'];
- *
- * @param string $group the name of the cache group to use [Optional]
- * @return Cache
- * @throws Cache_Exception
- */
- public static function instance($group = NULL)
- {
- // If there is no group supplied, try to get it from the config
- if ($group === NULL)
- {
- $group = KO7::$config->load('cache.default');
- }
- // If there is no group supplied
- if ($group === NULL)
- {
- // Use the default setting
- $group = Cache::$default;
- }
- if (isset(Cache::$instances[$group]))
- {
- // Return the current group if initiated already
- return Cache::$instances[$group];
- }
- $config = KO7::$config->load('cache');
- if ( ! $config->offsetExists($group))
- {
- throw new Cache_Exception(
- 'Failed to load KO7 Cache group: :group',
- [':group' => $group]
- );
- }
- $config = $config->get($group);
- // Create a new cache type instance
- $cache_class = 'Cache_'.ucfirst($config['driver']);
- Cache::$instances[$group] = new $cache_class($config);
- // Return the instance
- return Cache::$instances[$group];
- }
- /**
- * @var Config
- */
- protected $_config = [];
- /**
- * Ensures singleton pattern is observed, loads the default expiry
- *
- * @param array $config configuration
- */
- protected function __construct(array $config)
- {
- $this->config($config);
- }
- /**
- * Getter and setter for the configuration. If no argument provided, the
- * current configuration is returned. Otherwise the configuration is set
- * to this class.
- *
- * // Overwrite all configuration
- * $cache->config(array('driver' => 'memcache', '...'));
- *
- * // Set a new configuration setting
- * $cache->config('servers', array(
- * 'foo' => 'bar',
- * '...'
- * ));
- *
- * // Get a configuration setting
- * $servers = $cache->config('servers);
- *
- * @param mixed key to set to array, either array or config path
- * @param mixed value to associate with key
- * @return mixed
- */
- public function config($key = NULL, $value = NULL)
- {
- if ($key === NULL)
- return $this->_config;
- if (is_array($key))
- {
- $this->_config = $key;
- }
- else
- {
- if ($value === NULL)
- return Arr::get($this->_config, $key);
- $this->_config[$key] = $value;
- }
- return $this;
- }
- /**
- * Overload the __clone() method to prevent cloning
- *
- * @return void
- * @throws Cache_Exception
- */
- final public function __clone()
- {
- throw new Cache_Exception('Cloning of KO7_Cache objects is forbidden');
- }
- /**
- * Retrieve a cached value entry by id.
- *
- * // Retrieve cache entry from default group
- * $data = Cache::instance()->get('foo');
- *
- * // Retrieve cache entry from default group and return 'bar' if miss
- * $data = Cache::instance()->get('foo', 'bar');
- *
- * // Retrieve cache entry from memcache group
- * $data = Cache::instance('memcache')->get('foo');
- *
- * @param string $id id of cache to entry
- * @param string $default default value to return if cache miss
- * @return mixed
- * @throws Cache_Exception
- */
- abstract public function get($id, $default = NULL);
- /**
- * Set a value to cache with id and lifetime
- *
- * $data = 'bar';
- *
- * // Set 'bar' to 'foo' in default group, using default expiry
- * Cache::instance()->set('foo', $data);
- *
- * // Set 'bar' to 'foo' in default group for 30 seconds
- * Cache::instance()->set('foo', $data, 30);
- *
- * // Set 'bar' to 'foo' in memcache group for 10 minutes
- * if (Cache::instance('memcache')->set('foo', $data, 600))
- * {
- * // Cache was set successfully
- * return
- * }
- *
- * @param string $id id of cache entry
- * @param string $data data to set to cache
- * @param integer $lifetime lifetime in seconds
- * @return boolean
- */
- abstract public function set($id, $data, $lifetime = 3600);
- /**
- * Delete a cache entry based on id
- *
- * // Delete 'foo' entry from the default group
- * Cache::instance()->delete('foo');
- *
- * // Delete 'foo' entry from the memcache group
- * Cache::instance('memcache')->delete('foo')
- *
- * @param string $id id to remove from cache
- * @return boolean
- */
- abstract public function delete($id);
- /**
- * Delete all cache entries.
- *
- * Beware of using this method when
- * using shared memory cache systems, as it will wipe every
- * entry within the system for all clients.
- *
- * // Delete all cache entries in the default group
- * Cache::instance()->delete_all();
- *
- * // Delete all cache entries in the memcache group
- * Cache::instance('memcache')->delete_all();
- *
- * @return boolean
- */
- abstract public function delete_all();
- /**
- * Takes the sha1 of the id and adds prefix to avoid duplicates
- *
- * The id is converted to a sha1 to prevent any issues with
- * id length or any special character
- *
- * // Sanitize a cache id
- * $id = $this->_sanitize_id($id);
- *
- * @param string $id id of cache to sanitize
- * @return string
- */
- protected function _sanitize_id($id)
- {
- // adding cache prefix to avoid duplicates
- $prefix = '';
- // configuration for the specific cache group
- if (isset($this->_config['prefix']) AND $this->_config['prefix'] !== NULL)
- {
- $prefix = $this->_config['prefix'];
- }
- // prefix general configuration cache
- else
- {
- $prefix = KO7::$config->load('cache.prefix');
- }
- // sha1 the id makes sure name is not too long and has not any not allowed characters
- return $prefix.sha1($id);
- }
- }
- // End KO7_Cache
|