ModuleCache

Package framework.modules
Inheritance class ModuleCache » Module » LsObject
Since 1.0
Source Code /framework/classes/modules/cache/Cache.class.php
Модуль кеширования. Для реализации кеширования используетс библиотека Zend_Cache с бэкэндами File, Memcache и XCache. Т.к. в memcache нет встроенной поддержки тегирования при кешировании, то для реализации тегов используется враппер от Дмитрия Котерова - Dklab_Cache_Backend_TagEmuWrapper.

Пример использования:
   // Получает пользователя по его логину
   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

Hide inherited properties

PropertyTypeDescriptionDefined By
_aBehaviors Список поведений в виде готовых объектов, формируется автоматически LsObject
aBehaviors array Список поведений LsObject
aCacheBackends array Список бекендов кеширования ModuleCache
aStats array Статистика кеширования ModuleCache
bAllowForce bool Возможность принудительно использовать кешировоание, даже если оно отключено в конфиге ModuleCache
bAllowUse bool Разрешать или нет кеширование ModuleCache
bIsInit bool Указывает на то, была ли проведенна инициализация модуля Module
sCacheType string|null Дефолтный тип кеширования ModuleCache
sPrefixSmartCache string Префикс для "умного" кеширования ModuleCache

Public Methods

Hide inherited methods

MethodDescriptionDefined By
AddBehaviorHook() Добавляет хук поведения LsObject
AttachBehavior() Присоединяет поведение к объекту LsObject
CalcStats() Подсчет статистики использования кеша ModuleCache
Clean() Чистит кеши ModuleCache
ClearOldCache() Удаляет старый кеш в случайном порядке ModuleCache
Delete() Удаляет значение из кеша по ключу(имени) ModuleCache
DetachBehavior() Отсоединяет поведение от объекта LsObject
Get() Получить значение из кеша ModuleCache
GetBehavior() Возвращает объект поведения по его имени LsObject
GetBehaviors() Возвращает все объекты поведения LsObject
GetLife() Получает значение из текущего кеша сессии ModuleCache
GetStats() Возвращает статистику использования кеша ModuleCache
Init() Инициализация ModuleCache
InitParams() Инициализация необходимых параметров модуля ModuleCache
RemoveBehaviorHook() Удаляет хук поведения LsObject
RunBehaviorHook() Запускает хук поведения на выполнение LsObject
Set() Записать значение в кеш ModuleCache
SetInit() Помечает модуль как инициализированный Module
SetLife() Сохраняет значение в кеше на время исполнения скрипта(сессии), некий аналог Registry ModuleCache
Shutdown() Метод срабатывает при завершении работы ядра Module
SmartGet() Получения значения из "умного" кеша для борьбы с конкурирующими запросами ModuleCache
SmartSet() Устанавливаем значение в "умном" кеша для борьбы с конкурирующими запросами ModuleCache
__call() Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля LsObject
__clone() Блокируем копирование/клонирование объекта Module
__construct() Конструктор, запускается автоматически при создании объекта LsObject
__get() Обработка доступа к объекты поведения LsObject
isInit() Возвращает значение флага инициализации модуля Module

Protected Methods

Hide inherited methods

MethodDescriptionDefined By
GetCacheBackend() Возвращает объект бекенда кеша ModuleCache
HashName() Формирует хеш от имени ключа кеша ModuleCache
MultiGet() Поддержка мульти-запросов к кешу ModuleCache
PrepareBehaviors() Инициализация поведений LsObject

Property Details

aCacheBackends property
protected array $aCacheBackends;

Список бекендов кеширования

aStats property
protected array $aStats;

Статистика кеширования

bAllowForce property
protected bool $bAllowForce;

Возможность принудительно использовать кешировоание, даже если оно отключено в конфиге

bAllowUse property
protected bool $bAllowUse;

Разрешать или нет кеширование

sCacheType property
protected string|null $sCacheType;

Дефолтный тип кеширования

sPrefixSmartCache property
protected string $sPrefixSmartCache;

Префикс для "умного" кеширования

See Also

Method Details

CalcStats() method
public void CalcStats(int $iTime, string $sMethod)
$iTime int Время выполнения метода
$sMethod string имя метода
Source Code: /framework/classes/modules/cache/Cache.class.php#448 (show)
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']++;
    }
}

Подсчет статистики использования кеша

Clean() method
public bool Clean(string $cMode='all', array $aTags=array ( ), string|null $sCacheType=NULL, bool $bForce=false)
$cMode string Режим очистки кеша
$aTags array Список тегов, актуально для режима Zend_Cache::CLEANING_MODE_MATCHING_TAG
$sCacheType string|null Тип кеша
$bForce bool Принудительно использовать кеширование, даже если оно отключено в конфиге
{return} bool
Source Code: /framework/classes/modules/cache/Cache.class.php#404 (show)
public function Clean($cMode Zend_Cache::CLEANING_MODE_ALL$aTags = array(), $sCacheType null$bForce false)
{
    if (!
$this->bAllowUse and !($this->bAllowForce and $bForce)) {
        return 
false;
    }
    if (!
is_array($aTags)) {
        
$aTags = array($aTags);
    }
    
/**
     * Переводим теги с нижний регистр
     */
    
$aTags array_map('strtolower'$aTags);
    
$oCacheBackend $this->GetCacheBackend($sCacheType);
    return 
$oCacheBackend->Clean($cMode$aTags);
}

Чистит кеши

ClearOldCache() method
public void ClearOldCache()
Source Code: /framework/classes/modules/cache/Cache.class.php#142 (show)
public function ClearOldCache()
{
    
$this->Clean(Zend_Cache::CLEANING_MODE_OLD);
}

Удаляет старый кеш в случайном порядке Рекомендуется запускать раз в пару дней из под крона

Delete() method
public bool Delete(string $sName, string|null $sCacheType=NULL, bool $bForce=false)
$sName string
$sCacheType string|null
$bForce bool
{return} bool
Source Code: /framework/classes/modules/cache/Cache.class.php#382 (show)
public function Delete($sName$sCacheType null$bForce false)
{
    if (!
$this->bAllowUse and !($this->bAllowForce and $bForce)) {
        return 
false;
    }
    
/**
     * Удаляем данные их кеша
     */
    
$oCacheBackend $this->GetCacheBackend($sCacheType);
    return 
$oCacheBackend->Delete($this->HashName($sName));
}

Удаляет значение из кеша по ключу(имени)

Get() method
public mixed|bool Get(string|array $sName, string|null $sCacheType=NULL, bool $bForce=false, bool $bKeepInMemory=false)
$sName string|array Имя ключа
$sCacheType string|null Тип кеша
$bForce bool Принудительно использовать кеширование, даже если оно отключено в конфиге
$bKeepInMemory bool Если true, то данные дополнительно будут сохранены в памяти на время выполнения запроса (скрипта). В результате чего повторные Get() запросы к кешу будут значительно быстрее. Параметр не поддерживает мульти-запросы к кешу. Данные параметр следует использовать очень осторожно, т.к. кешированные данные нельзя будет обновить/удалить до конца выполнения запроса.
{return} mixed|bool
Source Code: /framework/classes/modules/cache/Cache.class.php#217 (show)
public function Get($sName$sCacheType null$bForce false$bKeepInMemory false)
{
    if (!
$this->bAllowUse and !($this->bAllowForce and $bForce)) {
        return 
false;
    }
    
/**
     * Запрос сразу на несколько ключей?
     */
    
if (is_array($sName)) {
        return 
$this->MultiGet($sName$sCacheType);
    }
    
/**
     * При необходимости смотрим в памяти
     */
    
if ($bKeepInMemory) {
        
$sKeyMemory 'auto_keep_in_memory_' $sName;
        if (
false !== ($mData $this->GetLife($sKeyMemory))) {
            return 
$mData;
        }
    }

    
$oCacheBackend $this->GetCacheBackend($sCacheType);
    
$mData $oCacheBackend->Get($this->HashName($sName));
    
/**
     * Сохраняем в памяти
     */
    
if ($bKeepInMemory and $mData !== false) {
        
$this->SetLife($mData$sKeyMemory);
    }
    return 
$mData;
}

Получить значение из кеша

GetCacheBackend() method
protected ModuleCache_EntityBackend GetCacheBackend(string|null $sCacheType=NULL)
$sCacheType string|null Тип кеша
{return} ModuleCache_EntityBackend Объект бекенда кеша
Source Code: /framework/classes/modules/cache/Cache.class.php#155 (show)
protected function GetCacheBackend($sCacheType null)
{
    if (
$sCacheType) {
        
$sCacheType strtolower($sCacheType);
    } else {
        
$sCacheType $this->sCacheType;
    }
    
/**
     * Устанавливает алиас memory == memcached
     */
    
if ($sCacheType == 'memory') {
        
$sCacheType 'memcached';
    }
    if (isset(
$this->aCacheBackends[$sCacheType])) {
        return 
$this->aCacheBackends[$sCacheType];
    }
    
$sCacheTypeCam func_camelize($sCacheType);
    
/**
     * Формируем имя класса бекенда
     */
    
$sClass "ModuleCache_EntityBackend{$sCacheTypeCam}";
    
$sClass Engine::GetEntityClass($sClass);
    if (
class_exists($sClass)) {
        
/**
         * Создаем объект и проверяем доступность его использования
         */
        
$oBackend = new $sClass;
        if (
true === ($mResult $oBackend->IsAvailable())) {
            
$oBackend->Init(array('stats_callback' => array($this'CalcStats')));
            
$this->aCacheBackends[$sCacheType] = $oBackend;
            return 
$oBackend;
        } else {
            throw new 
Exception("Cache '{$sCacheTypeCam}' not available: {$mResult}");
        }
    }
    throw new 
Exception("Not found class for cache type: " $sCacheTypeCam);
}

Возвращает объект бекенда кеша

GetLife() method
public mixed GetLife(string $sName)
$sName string Имя ключа
{return} mixed
Source Code: /framework/classes/modules/cache/Cache.class.php#426 (show)
public function GetLife($sName)
{
    return 
$this->Get($sName'life'true);
}

Получает значение из текущего кеша сессии

GetStats() method
public array GetStats()
{return} array
Source Code: /framework/classes/modules/cache/Cache.class.php#465 (show)
public function GetStats()
{
    return 
$this->aStats;
}

Возвращает статистику использования кеша

HashName() method
protected string HashName(string $sName)
$sName string Имя ключа кеша
{return} string
Source Code: /framework/classes/modules/cache/Cache.class.php#200 (show)
protected function HashName($sName)
{
    return 
md5(Config::Get('sys.cache.prefix') . $sName);
}

Формирует хеш от имени ключа кеша

Init() method
public void Init()
Source Code: /framework/classes/modules/cache/Cache.class.php#121 (show)
public function Init()
{
    
$this->InitParams();
}

Инициализация

InitParams() method
public void InitParams()
Source Code: /framework/classes/modules/cache/Cache.class.php#129 (show)
public function InitParams()
{
    
$this->bAllowUse = (bool)Config::Get('sys.cache.use');
    if (
is_bool(Config::Get('sys.cache.force'))) {
        
$this->bAllowForce Config::Get('sys.cache.force');
    }
    
$this->sCacheType strtolower(Config::Get('sys.cache.type'));
}

Инициализация необходимых параметров модуля

MultiGet() method
protected bool|array MultiGet(array $aName, string|null $sCacheType=NULL)
$aName array Имя ключа
$sCacheType string|null Тип кеша
{return} bool|array
Source Code: /framework/classes/modules/cache/Cache.class.php#283 (show)
protected function MultiGet($aName$sCacheType null)
{
    if (!
count($aName)) {
        return 
false;
    }
    
$oCacheBackend $this->GetCacheBackend($sCacheType);
    if (
$oCacheBackend->IsAllowMultiGet()) {
        
$aKeys = array();
        
$aKv = array();
        foreach (
$aName as $sName) {
            
$sHash $this->HashName($sName);
            
$aKeys[] = $sHash;
            
$aKv[$sHash] = $sName;
        }
        
$data $oCacheBackend->Get($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 $sName) {
            if ((
false !== ($data $oCacheBackend->Get($this->HashName($sName))))) {
                
$aData[$sName] = $data;
            }
        }
        if (
count($aData) > 0) {
            return 
$aData;
        }
        return 
false;
    }
}

Поддержка мульти-запросов к кешу Такие запросы поддерживает только memcached, поэтому для остальных типов делаем эмуляцию

Set() method
public bool Set(mixed $mData, string $sName, array|string $aTags=array ( ), int|bool $iTimeLife=false, string|null $sCacheType=NULL, bool $bForce=false)
$mData mixed Данные для хранения в кеше
$sName string Имя ключа
$aTags array|string Список тегов, для возможности удалять сразу несколько кешей по тегу
$iTimeLife int|bool Время жизни кеша в секундах
$sCacheType string|null Тип кеша
$bForce bool Принудительно использовать кеширование, даже если оно отключено в конфиге
{return} bool
Source Code: /framework/classes/modules/cache/Cache.class.php#334 (show)
public function Set($mData$sName$aTags = array(), $iTimeLife false$sCacheType null$bForce false)
{
    if (!
$this->bAllowUse and !($this->bAllowForce and $bForce)) {
        return 
false;
    }
    if (!
is_array($aTags)) {
        
$aTags = array($aTags);
    }
    
/**
     * Переводим теги с нижний регистр
     */
    
$aTags array_map('strtolower'$aTags);
    
/**
     * Сохраняем данные в кеш
     */
    
$oCacheBackend $this->GetCacheBackend($sCacheType);
    return 
$oCacheBackend->Set($mData$this->HashName($sName), $aTags$iTimeLife);
}

Записать значение в кеш

SetLife() method
public void SetLife(mixed $mData, string $sName)
$mData mixed Данные для сохранения в кеше
$sName string Имя ключа
Source Code: /framework/classes/modules/cache/Cache.class.php#437 (show)
public function SetLife($mData$sName)
{
    
$this->Set($mData$sName, array(), false'life'true);
}

Сохраняет значение в кеше на время исполнения скрипта(сессии), некий аналог Registry

SmartGet() method
public bool|mixed SmartGet(string $sName, string|null $sCacheType=NULL, bool $bForce=false)
$sName string Имя ключа
$sCacheType string|null Тип кеша
$bForce bool Принудительно использовать кеширование, даже если оно отключено в конфиге
{return} bool|mixed
Source Code: /framework/classes/modules/cache/Cache.class.php#260 (show)
public function SmartGet($sName$sCacheType null$bForce false)
{
    if (!
$this->bAllowUse and !($this->bAllowForce and $bForce)) {
        return 
false;
    }
    
/**
     * Если данных в основном кеше нет, то перекладываем их из временного
     */
    
if (($data $this->Get($sName$sCacheType$bForce)) === false) {
        
$this->Set($this->Get($this->sPrefixSmartCache $sName$sCacheType$bForce), $sName, array(), 60,
            
$sCacheType$bForce); // храним данные из временного в основном не долго
    
}
    return 
$data;
}

Получения значения из "умного" кеша для борьбы с конкурирующими запросами Если кеш "протух", и за ним обращаются много запросов, то только первый запрос вернет FALSE, остальные будут получать чуть устаревшие данные из временного кеша, пока их не обновит первый запрос Текущая реализация имеет недостаток - размер кеша увеличивается в два раза

SmartSet() method
public bool SmartSet(mixed $data, string $sName, array $aTags=array ( ), int|bool $iTimeLife=false, string|null $sCacheType=NULL, bool $bForce=false)
$data mixed Данные для хранения в кеше
$sName string Имя ключа
$aTags array Список тегов, для возможности удалять сразу несколько кешей по тегу
$iTimeLife int|bool Время жизни кеша в секундах
$sCacheType string|null Тип кеша
$bForce bool Принудительно использовать кеширование, даже если оно отключено в конфиге
{return} bool
Source Code: /framework/classes/modules/cache/Cache.class.php#366 (show)
public function SmartSet($data$sName$aTags = array(), $iTimeLife false$sCacheType null$bForce false)
{
    
$this->Set($data$this->sPrefixSmartCache $sName, array(), $iTimeLife !== false $iTimeLife 60 false,
        
$sCacheType$bForce);
    return 
$this->Set($data$sName$aTags$iTimeLife$sCacheType$bForce);
}

Устанавливаем значение в "умном" кеша для борьбы с конкурирующими запросами Дополнительно сохраняет значение во временном кеше на чуть большее время