ModuleCache
Package | engine.modules |
---|---|
Inheritance | class ModuleCache » Module » LsObject |
Since | 1.0 |
Source Code | /engine/modules/cache/Cache.class.php |
Пример использования:
// Получает пользователя по его логину public function GetUserByLogin($sLogin) { // Пытаемся получить значение из кеша if (false === ($oUser = $this->Cache_Get("user_login_{$sLogin}"))) { // Если значение из кеша получить не удалось, то обращаемся к базе данных $oUser = $this->oMapper->GetUserByLogin($sLogin); // Записываем значение в кеш $this->Cache_Set($oUser, "user_login_{$sLogin}", array(), 60*60*24*5); } return $oUser; } // Обновляет пользовател в БД public function UpdateUser($oUser) { // Удаляем кеш конкретного пользователя $this->Cache_Delete("user_login_{$oUser->getLogin()}"); // Удалем кеш со списком всех пользователей $this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array('user_update')); // Обновлем пользовател в базе данных return $this->oMapper->UpdateUser($oUser); } // Получает список всех пользователей public function GetUsers() { // Пытаемся получить значение из кеша if (false === ($aUserList = $this->Cache_Get("users"))) { // Если значение из кеша получить не удалось, то обращаемся к базе данных $aUserList = $this->oMapper->GetUsers(); // Записываем значение в кеш $this->Cache_Set($aUserList, "users", array('user_update'), 60*60*24*5); } return $aUserList; }
Protected Properties
Property | Type | Description | Defined By |
---|---|---|---|
aStats | array | Статистика кеширования | ModuleCache |
aStoreLife | array | Хранилище для кеша на время сессии | ModuleCache |
bIsInit | bool | Указывает на то, была ли проведенна инициализация модуля | Module |
bUseCache | bool | Используется кеширование или нет | ModuleCache |
oBackendCache | Zend_Cache_Backend | Объект бэкенда кеширования | ModuleCache |
oEngine | Engine | Объект ядра | Module |
sCacheType | string | Тип кеширования, прописан в глобльном конфиге config.php | ModuleCache |
sPrefixSmartCache | string | Префикс для "умного" кеширования | ModuleCache |
Public Methods
Method | Description | Defined By |
---|---|---|
CalcStats() | Подсчет статистики использования кеша | ModuleCache |
Clean() | Чистит кеши | ModuleCache |
Delete() | Удаляет значение из кеша по ключу(имени) | ModuleCache |
Get() | Получить значение из кеша | ModuleCache |
GetLife() | Получает значение из текущего кеша сессии | ModuleCache |
GetStats() | Возвращает статистику использования кеша | ModuleCache |
Init() | Инициализируем нужный тип кеша | ModuleCache |
Set() | Записать значение в кеш | ModuleCache |
SetInit() | Помечает модуль как инициализированный | Module |
SetLife() | Сохраняет значение в кеше на время исполнения скрипта(сессии), некий аналог Registry | ModuleCache |
Shutdown() | Метод срабатывает при завершении работы ядра | Module |
SmartGet() | Получения значения из "умного" кеша для борьбы с конкурирующими запросами | ModuleCache |
SmartSet() | Устанавливаем значение в "умном" кеша для борьбы с конкурирующими запросами | ModuleCache |
__call() | Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля | Module |
__construct() | При создании модуля передаем объект ядра | Module |
isInit() | Возвращает значение флага инициализации модуля | Module |
multiGet() | Поддержка мульти-запросов к кешу | ModuleCache |
Protected Methods
Method | Description | Defined By |
---|---|---|
__clone() | Блокируем копирование/клонирование объекта | Module |
Property Details
Статистика кеширования
Хранилище для кеша на время сессии
Используется кеширование или нет
Объект бэкенда кеширования
Тип кеширования, прописан в глобльном конфиге config.php
Префикс для "умного" кеширования
Method Details
public void CalcStats(int $iTime, string $sMethod)
| ||
$iTime | int | Время выполнения метода |
$sMethod | string | имя метода |
public function CalcStats($iTime,$sMethod) {
$this->aStats['time']+=$iTime;
$this->aStats['count']++;
if ($sMethod=='Dklab_Cache_Backend_Profiler::load') {
$this->aStats['count_get']++;
}
if ($sMethod=='Dklab_Cache_Backend_Profiler::save') {
$this->aStats['count_set']++;
}
}
Подсчет статистики использования кеша
public bool Clean(int $cMode='all', array $aTags=array (
))
| ||
$cMode | int | Режим очистки кеша |
$aTags | array | Список тегов, актуально для режима Zend_Cache::CLEANING_MODE_MATCHING_TAG |
{return} | bool |
public function Clean($cMode = Zend_Cache::CLEANING_MODE_ALL, $aTags = array()) {
if (!$this->bUseCache) {
return false;
}
return $this->oBackendCache->clean($cMode,$aTags);
}
Чистит кеши
public bool Delete(string $sName)
| ||
$sName | string | Имя ключа |
{return} | bool |
public function Delete($sName) {
if (!$this->bUseCache) {
return false;
}
/**
* Т.к. название кеша может быть любым то предварительно хешируем имя кеша
*/
$sName=md5(Config::Get('sys.cache.prefix').$sName);
return $this->oBackendCache->remove($sName);
}
Удаляет значение из кеша по ключу(имени)
public mixed|bool Get(string $sName)
| ||
$sName | string | Имя ключа |
{return} | mixed|bool |
public function Get($sName) {
if (!$this->bUseCache) {
return false;
}
/**
* Т.к. название кеша может быть любым то предварительно хешируем имя кеша
*/
if (!is_array($sName)) {
$sName=md5(Config::Get('sys.cache.prefix').$sName);
$data=$this->oBackendCache->load($sName);
if ($this->sCacheType==SYS_CACHE_TYPE_FILE and $data!==false) {
return unserialize($data);
} else {
return $data;
}
} else {
return $this->multiGet($sName);
}
}
Получить значение из кеша
public mixed GetLife(string $sName)
| ||
$sName | string | Имя ключа |
{return} | mixed |
public function GetLife($sName) {
if (key_exists($sName,$this->aStoreLife)) {
return $this->aStoreLife[$sName];
}
return false;
}
Получает значение из текущего кеша сессии
public array GetStats()
| ||
{return} | array |
public function GetStats() {
return $this->aStats;
}
Возвращает статистику использования кеша
public void Init()
|
public function Init() {
$this->bUseCache=Config::Get('sys.cache.use');
$this->sCacheType=Config::Get('sys.cache.type');
if (!$this->bUseCache) {
return false;
}
/**
* Файловый кеш
*/
if ($this->sCacheType==SYS_CACHE_TYPE_FILE) {
require_once(LS_DKCACHE_PATH.'Zend/Cache/Backend/File.php');
$oCahe = new Zend_Cache_Backend_File(
array(
'cache_dir' => Config::Get('sys.cache.dir'),
'file_name_prefix' => Config::Get('sys.cache.prefix'),
'read_control_type' => 'crc32',
'hashed_directory_level' => Config::Get('sys.cache.directory_level'),
'read_control' => true,
'file_locking' => true,
)
);
$this->oBackendCache = new Dklab_Cache_Backend_Profiler($oCahe,array($this,'CalcStats'));
/**
* Кеш на основе Memcached
*/
} elseif ($this->sCacheType==SYS_CACHE_TYPE_MEMORY) {
require_once(LS_DKCACHE_PATH.'Zend/Cache/Backend/Memcached.php');
$aConfigMem=Config::Get('memcache');
$oCahe = new Dklab_Cache_Backend_MemcachedMultiload($aConfigMem);
$this->oBackendCache = new Dklab_Cache_Backend_TagEmuWrapper(new Dklab_Cache_Backend_Profiler($oCahe,array($this,'CalcStats')));
/**
* Кеш на основе XCache
*/
} elseif ($this->sCacheType==SYS_CACHE_TYPE_XCACHE) {
require_once(LS_DKCACHE_PATH.'Zend/Cache/Backend/Xcache.php');
$aConfigMem=Config::Get('xcache');
$oCahe = new Zend_Cache_Backend_Xcache(is_array($aConfigMem) ? $aConfigMem : array());
$this->oBackendCache = new Dklab_Cache_Backend_TagEmuWrapper(new Dklab_Cache_Backend_Profiler($oCahe,array($this,'CalcStats')));
} else {
throw new Exception("Wrong type of caching: ".$this->sCacheType." (file, memory, xcache)");
}
/**
* Дабы не засорять место протухшим кешем, удаляем его в случайном порядке, например 1 из 50 раз
*/
if (rand(1,50)==33) {
$this->Clean(Zend_Cache::CLEANING_MODE_OLD);
}
}
Инициализируем нужный тип кеша
public bool Set(mixed $data, string $sName, array $aTags=array (
), int $iTimeLife=false)
| ||
$data | mixed | Данные для хранения в кеше |
$sName | string | Имя ключа |
$aTags | array | Список тегов, для возможности удалять сразу несколько кешей по тегу |
$iTimeLife | int | Время жизни кеша в секундах |
{return} | bool |
public function Set($data,$sName,$aTags=array(),$iTimeLife=false) {
if (!$this->bUseCache) {
return false;
}
/**
* Т.к. название кеша может быть любым то предварительно хешируем имя кеша
*/
$sName=md5(Config::Get('sys.cache.prefix').$sName);
if ($this->sCacheType==SYS_CACHE_TYPE_FILE) {
$data=serialize($data);
}
return $this->oBackendCache->save($data,$sName,$aTags,$iTimeLife);
}
Записать значение в кеш
public void SetLife(mixed $data, string $sName)
| ||
$data | mixed | Данные для сохранения в кеше |
$sName | string | Имя ключа |
public function SetLife($data,$sName) {
$this->aStoreLife[$sName]=$data;
}
Сохраняет значение в кеше на время исполнения скрипта(сессии), некий аналог Registry
public bool|mixed SmartGet($sName $sName)
| ||
$sName | $sName | Имя ключа |
{return} | bool|mixed |
public function SmartGet($sName) {
if (!$this->bUseCache) {
return false;
}
/**
* Если данных в основном кеше нет, то перекладываем их из временного
*/
if (($data=$this->Get($sName))===false) {
$this->Set($this->Get($this->sPrefixSmartCache.$sName),$sName,array(),60); // храним данные из временного в основном не долго
}
return $data;
}
Получения значения из "умного" кеша для борьбы с конкурирующими запросами Если кеш "протух", и за ним обращаются много запросов, то только первый запрос вернет FALSE, остальные будут получать чуть устаревшие данные из временного кеша, пока их не обновит первый запрос
public bool SmartSet(mixed $data, string $sName, array $aTags=array (
), int $iTimeLife=false)
| ||
$data | mixed | Данные для хранения в кеше |
$sName | string | Имя ключа |
$aTags | array | Список тегов, для возможности удалять сразу несколько кешей по тегу |
$iTimeLife | int | Время жизни кеша в секундах |
{return} | bool |
public function SmartSet($data,$sName,$aTags=array(),$iTimeLife=false) {
$this->Set($data,$this->sPrefixSmartCache.$sName,array(),$iTimeLife!==false ? $iTimeLife+60 : false);
return $this->Set($data,$sName,$aTags,$iTimeLife);
}
Устанавливаем значение в "умном" кеша для борьбы с конкурирующими запросами Дополнительно сохраняет значение во временном кеше на чуть большее время
public bool|array multiGet(array $aName)
| ||
$aName | array | Имя ключа |
{return} | bool|array |
public function multiGet($aName) {
if (count($aName)==0) {
return false;
}
if ($this->sCacheType==SYS_CACHE_TYPE_MEMORY) {
$aKeys=array();
$aKv=array();
foreach ($aName as $sName) {
$aKeys[]=md5(Config::Get('sys.cache.prefix').$sName);
$aKv[md5(Config::Get('sys.cache.prefix').$sName)]=$sName;
}
$data=$this->oBackendCache->load($aKeys);
if ($data and is_array($data)) {
$aData=array();
foreach ($data as $key => $value) {
$aData[$aKv[$key]]=$value;
}
if (count($aData)>0) {
return $aData;
}
}
return false;
} else {
$aData=array();
foreach ($aName as $key => $sName) {
if ((false !== ($data = $this->Get($sName)))) {
$aData[$sName]=$data;
}
}
if (count($aData)>0) {
return $aData;
}
return false;
}
}
Поддержка мульти-запросов к кешу Такие запросы поддерживает только memcached, поэтому для остальных типов делаем эмуляцию