Натакал класс для работы с кешем. Класс использует основные операции (get, set, inc, dec, exists, delete). Плюс класса в том, что использует разные системы кеширования и расширяем (не помню какой паттерн). На данный момент работает с xCache, eAccelerator, APC Код (Text): <?php /** *Класс, реализующий API для доступа к разным видам кэша */ class cache { /** * Используемый кэш * @var string */ private $_cache_type = 'auto'; /** * Указатель на используемый класс с кэшем * @var object */ private $_cache = null; /** * Префикс для ключей * @var string */ private $_prefix = ''; /** * Проверка возможности кэширования * * @return boolean */ public static function isEnable() { $cache_systems = array(); if (function_exists('eaccelerator_get')) $cache_systems[] = 'eaccelerator'; if (function_exists('apc_fetch')) $cache_systems[] = 'apc'; if (function_exists('xcache_get')) $cache_systems[] = 'xcache'; if (class_exists('Memcache')) $cache_systems[] = 'memcache'; return (sizeof($cache_systems)) ? $cache_systems : false; } /** * Конструктор класса * * @param array $options - ассоциативный массив с опциями для выбора кеша и настроек * @return boolean - результат инициализации кеша */ public function __construct($options = null) { $required_cache = isset($options['cache']) ? : $this->_cache_type; if ($cache_systems = $this->isEnable()) { if ($required_cache == 'auto') $this->_cache_type = array_shift($cache_systems); // первое значение в списке else if (in_array($required_cache, $cache_systems)) $this->_cache_type = $required_cache; else return false; } else return false; if (!empty($options['prefix'])) $this->_prefix = $options['prefix']; $this->_cache = new $this->_cache_type($options); return ($this->_cache) ? true : false; } public function __destruct() { $this->_cache->__destruct(); } /** * Получение значения * * @param string $key * @return mixed */ public function get($key) { return $this->_cache->get($this->_prefix . $key); } /** * Установка значения * * @param string $key - ключ * @param mixed $data - данные * @param int $ttl - время жизни */ public function set($key, &$data, $ttl = 3600) { return $this->_cache->set($this->_prefix . $key, &$data, $ttl); } /** * Удаление ключа * * @param string $key * @return boolean */ public function delete($key) { return $this->_cache->delete($this->_prefix . $key); } /** * Проверка ключа на существование * * @param string $key * @return boolean */ public function exists($key) { return $this->_cache->exists($this->_prefix . $key); } /** * Инкремент данных * * @param string $key * @param int $val */ public function inc($key, $val = 1) { $this->_cache->inc($this->_prefix . $key, $val); } /** * Декремент данных * * @param string $key * @param int $val */ public function dec($key, $val = 1) { $this->_cache->dec($this->_prefix . $key, $val); } } /** * Обертка для кэшей */ class cache_container { public function __construct() { } public function __destruct() { } public function exists() { return false; } public function get() { return false; } public function set() { return false; } public function delete() { return false; } public function inc() { return false; } public function dec() { return false; } } /** * xCache */ class xcache extends cache_container { public function get($key) { return xcache_get($key); } public function set($key, &$data, $ttl) { return xcache_set($key, $data, $ttl); } public function delete($key) { return xcache_unset($key); } public function exists($key) { return xcache_isset($key); } public function inc($key, $val = 1) { xcache_inc($key, $val); } public function dec($key, $val = 1) { xcache_dec($key, $val); } } /** * APC */ class apc extends cache_container { public function get($key) { return apc_fetch($key); } public function set($key, &$data, $ttl) { return apc_store($key, $data, $ttl); } public function delete($key) { return apc_delete($key); } public function exists($key) { return apc_exists($key); } public function inc($key, $val = 1) { apc_inc($key, $val); } public function dec($key, $val = 1) { apc_dec($key, $val); } } /** * eAccelerator */ class eaccelerator extends cache_container { public function get($key) { return eaccelerator_get($key); } public function set($key, &$data, $ttl = 0) { return eaccelerator_put($key, $data, $ttl); } public function delete($key) { return eaccelerator_rm($key); } public function exists($key) { return ($this->get($key)) ? true : false; } public function inc($key, $val = 1) { $this->set($key, $this->get($key) + $val); } public function dec($key, $val = 1) { $this->set($key, $this->get($key) - $val); } } Потом задумался над хранением сессий в кеше и написал следующий класс: Код (Text): <?php /** * Хранение сессий в кэше * * Использование: * CacheSessionHandler::instance(); * session_start(); */ class cacheSessionHandler { private static $cache; private static $ttl; public static function instance() { static $self = false; if (false === $self) { $self = new cacheSessionHandler(); } return $self; } private function __construct() { session_set_save_handler(array(__CLASS__, 'open'), array(__CLASS__, 'close'), array(__CLASS__, 'read'), array(__CLASS__, 'write'), array(__CLASS__, 'destroy'), array(__CLASS__, 'gc')); self::$cache = new cache(); self::$ttl = (int) get_cfg_var('session.gc_maxlifetime'); } public function __destruct() { session_write_close(); } public static function open($save_path, $session_name) { return true; } public static function close() { return true; } public static function read($session_id) { return self::$cache->get('session/' . $session_id); } public static function write($session_id, $session_data) { return self::$cache->set('session/' . $session_id, $session_data, self::$ttl); } public static function destroy($session_id) { self::$cache->delete('session/' . $session_id); return true; } public static function gc($max_lifetime) { return true; } } В случае с memcache всё было бы ещё проще - две строки в php.ini сменить. В планах допиливание класса под работу с memcache. Интересно Ваше мнение Добавлено спустя 26 минут 5 секунд: И наконец использование: Код (Text): if (cache::isEnable()) { $cache = new cache(); $data = $cache->get('data'); if (!$data) { $data = ''; // Обычный способ получения данных $cache->set('data', $data); } } else { $data = ''; // Обычный способ получения данных }
У меня сессии в редисе торчат и зачем их кешировать еще - вообще не понимаю. И так на грани фантастики работать должно. И причем тут кеширование байт-кода средствами xCache, eAccelerator и обычное хранение данных (строк, массивов и пр.) в мемкеше? Я мож тут что-то не понял просто.
Обычное хранение данных работает и в APC, и в xCache и в eAccelerator. В ряде тестов мемкеш проигрывает по скорости перечисленным ранее именно при работе с данными. Редис использую на другом сервере - там другой бубен =)
Смотри, все данные у меня в редисе висят. Только данные, которые я юзаю - массивы всякие, строки. Типа аналог mysql. Только проще и быстрее. Для кеширования у меня заюзан xCache. Он кеширует байт-код пхп-страниц. То есть в самом коде нигде намека о xCache, он просто подключен в качестве либы и отдельно себе там работает. Код под него никак не изменяется. В каком месте здесь должен встрять твой класс? Просто хранить результат выполнения отдельного куска пхп-кода с помощью твоего класса, вместо того, что этот кусок будет каждый раз отрабатываться?
Это альтернатива редису. Можно хоть tmpFS сделать кэшем - зависит от религиозных убеждений программиста. Мо класс для тех, у кого нет редиса, но стоит какая-либо кэш-система