2009-05-10 10:50:39 +03:00
|
|
|
|
<?php
|
2008-09-21 09:36:57 +03:00
|
|
|
|
/*-------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* LiveStreet Engine Social Networking
|
|
|
|
|
* Copyright © 2008 Mzhelskiy Maxim
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* Official site: www.livestreet.ru
|
|
|
|
|
* Contact e-mail: rus.engine@gmail.com
|
|
|
|
|
*
|
|
|
|
|
* GNU General Public License, version 2:
|
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
|
*
|
|
|
|
|
---------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
2009-08-19 17:53:16 +03:00
|
|
|
|
require_once(Config::Get('path.root.engine').'/lib/external/DklabCache/config.php');
|
2010-05-22 14:58:49 +03:00
|
|
|
|
require_once(LS_DKCACHE_PATH.'Zend/Cache.php');
|
|
|
|
|
require_once(LS_DKCACHE_PATH.'Cache/Backend/MemcachedMultiload.php');
|
|
|
|
|
require_once(LS_DKCACHE_PATH.'Cache/Backend/TagEmuWrapper.php');
|
|
|
|
|
require_once(LS_DKCACHE_PATH.'Cache/Backend/Profiler.php');
|
2008-09-21 09:36:57 +03:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Типы кеширования: file и memory
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
define('SYS_CACHE_TYPE_FILE','file');
|
|
|
|
|
define('SYS_CACHE_TYPE_MEMORY','memory');
|
2011-04-25 21:23:44 +03:00
|
|
|
|
define('SYS_CACHE_TYPE_XCACHE','xcache');
|
2008-09-21 09:36:57 +03:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Модуль кеширования
|
|
|
|
|
* Работает в двух режимах: файловый кеш через Cache Lite и кеш в памяти через Memcache
|
|
|
|
|
*
|
|
|
|
|
*/
|
2010-05-27 17:02:43 +03:00
|
|
|
|
class ModuleCache extends Module {
|
2008-09-21 09:36:57 +03:00
|
|
|
|
|
|
|
|
|
protected $oBackendCache=null;
|
2009-08-19 17:53:16 +03:00
|
|
|
|
protected $bUseCache;
|
2008-09-21 09:36:57 +03:00
|
|
|
|
/**
|
|
|
|
|
* Тип кеширования, прописан в глобльном конфиге config.php
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
2009-08-19 17:53:16 +03:00
|
|
|
|
protected $sCacheType;
|
2008-09-21 09:36:57 +03:00
|
|
|
|
|
|
|
|
|
protected $aStats=array(
|
|
|
|
|
'time' =>0,
|
|
|
|
|
'count' => 0,
|
|
|
|
|
'count_get' => 0,
|
|
|
|
|
'count_set' => 0,
|
|
|
|
|
);
|
|
|
|
|
|
2011-02-27 16:46:01 +02:00
|
|
|
|
protected $aStoreLife=array();
|
2008-09-21 09:36:57 +03:00
|
|
|
|
/**
|
|
|
|
|
* Инициализируем нужный тип кеша
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public function Init() {
|
2009-08-19 17:53:16 +03:00
|
|
|
|
$this->bUseCache=Config::Get('sys.cache.use');
|
|
|
|
|
$this->sCacheType=Config::Get('sys.cache.type');
|
|
|
|
|
|
2008-09-21 09:36:57 +03:00
|
|
|
|
if (!$this->bUseCache) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if ($this->sCacheType==SYS_CACHE_TYPE_FILE) {
|
2010-05-22 14:58:49 +03:00
|
|
|
|
require_once(LS_DKCACHE_PATH.'Zend/Cache/Backend/File.php');
|
2008-09-21 09:36:57 +03:00
|
|
|
|
$oCahe = new Zend_Cache_Backend_File(
|
|
|
|
|
array(
|
2009-08-19 17:53:16 +03:00
|
|
|
|
'cache_dir' => Config::Get('sys.cache.dir'),
|
|
|
|
|
'file_name_prefix' => Config::Get('sys.cache.prefix'),
|
2008-09-21 09:36:57 +03:00
|
|
|
|
'read_control_type' => 'crc32',
|
2010-01-11 15:41:00 +02:00
|
|
|
|
'hashed_directory_level' => Config::Get('sys.cache.directory_level'),
|
2008-09-21 09:36:57 +03:00
|
|
|
|
'read_control' => true,
|
|
|
|
|
'file_locking' => true,
|
|
|
|
|
)
|
|
|
|
|
);
|
2009-04-27 22:57:43 +03:00
|
|
|
|
$this->oBackendCache = new Dklab_Cache_Backend_Profiler($oCahe,array($this,'CalcStats'));
|
2008-09-21 09:36:57 +03:00
|
|
|
|
} elseif ($this->sCacheType==SYS_CACHE_TYPE_MEMORY) {
|
2010-05-22 14:58:49 +03:00
|
|
|
|
require_once(LS_DKCACHE_PATH.'Zend/Cache/Backend/Memcached.php');
|
2009-08-19 17:53:16 +03:00
|
|
|
|
$aConfigMem=Config::Get('memcache');
|
|
|
|
|
|
2009-05-23 11:03:46 +03:00
|
|
|
|
$oCahe = new Dklab_Cache_Backend_MemcachedMultiload($aConfigMem);
|
2009-04-27 22:57:43 +03:00
|
|
|
|
$this->oBackendCache = new Dklab_Cache_Backend_TagEmuWrapper(new Dklab_Cache_Backend_Profiler($oCahe,array($this,'CalcStats')));
|
2011-04-25 21:23:44 +03:00
|
|
|
|
} 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')));
|
2008-09-21 09:36:57 +03:00
|
|
|
|
} else {
|
2011-04-25 21:23:44 +03:00
|
|
|
|
throw new Exception("Wrong type of caching: ".$this->sCacheType." (file, memory, xcache)");
|
2008-09-21 09:36:57 +03:00
|
|
|
|
}
|
2008-10-26 22:04:05 +02:00
|
|
|
|
/**
|
|
|
|
|
* Дабы не засорять место протухшим кешем, удаляем его в случайном порядке, например 1 из 50 раз
|
|
|
|
|
*/
|
|
|
|
|
if (rand(1,50)==33) {
|
2009-07-26 16:43:16 +03:00
|
|
|
|
$this->Clean(Zend_Cache::CLEANING_MODE_OLD);
|
2008-10-26 22:04:05 +02:00
|
|
|
|
}
|
2008-09-21 09:36:57 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Получить значение из кеша
|
|
|
|
|
*
|
|
|
|
|
* @param string $sName
|
|
|
|
|
* @return unknown
|
|
|
|
|
*/
|
2009-11-22 20:59:19 +02:00
|
|
|
|
public function Get($sName) {
|
2008-09-21 09:36:57 +03:00
|
|
|
|
if (!$this->bUseCache) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Т.к. название кеша может быть любым то предварительно хешируем имя кеша
|
|
|
|
|
*/
|
2009-05-23 11:03:46 +03:00
|
|
|
|
if (!is_array($sName)) {
|
2009-08-19 17:53:16 +03:00
|
|
|
|
$sName=md5(Config::Get('sys.cache.prefix').$sName);
|
2009-05-25 09:59:19 +03:00
|
|
|
|
$data=$this->oBackendCache->load($sName);
|
|
|
|
|
if ($this->sCacheType==SYS_CACHE_TYPE_FILE and $data!==false) {
|
|
|
|
|
return unserialize($data);
|
2009-05-23 11:03:46 +03:00
|
|
|
|
} else {
|
2009-05-25 09:59:19 +03:00
|
|
|
|
return $data;
|
2009-05-23 11:03:46 +03:00
|
|
|
|
}
|
2009-04-27 22:57:43 +03:00
|
|
|
|
} else {
|
2009-05-23 11:03:46 +03:00
|
|
|
|
return $this->multiGet($sName);
|
2009-04-27 22:57:43 +03:00
|
|
|
|
}
|
2008-09-21 09:36:57 +03:00
|
|
|
|
}
|
2009-05-23 11:03:46 +03:00
|
|
|
|
/**
|
|
|
|
|
* псевдо поддержка мульти-запросов к кешу
|
|
|
|
|
*
|
2009-11-22 20:59:19 +02:00
|
|
|
|
* @param array $aName
|
|
|
|
|
* @return bool|array
|
2009-05-23 11:03:46 +03:00
|
|
|
|
*/
|
|
|
|
|
public function multiGet($aName) {
|
2009-07-26 16:43:16 +03:00
|
|
|
|
if (count($aName)==0) {
|
|
|
|
|
return false;
|
2009-05-23 11:03:46 +03:00
|
|
|
|
}
|
2009-07-26 16:43:16 +03:00
|
|
|
|
if ($this->sCacheType==SYS_CACHE_TYPE_MEMORY) {
|
|
|
|
|
$aKeys=array();
|
|
|
|
|
$aKv=array();
|
|
|
|
|
foreach ($aName as $sName) {
|
2009-08-19 17:53:16 +03:00
|
|
|
|
$aKeys[]=md5(Config::Get('sys.cache.prefix').$sName);
|
|
|
|
|
$aKv[md5(Config::Get('sys.cache.prefix').$sName)]=$sName;
|
2009-07-26 16:43:16 +03:00
|
|
|
|
}
|
|
|
|
|
$data=$this->oBackendCache->load($aKeys);
|
|
|
|
|
if ($data and is_array($data)) {
|
|
|
|
|
$aData=array();
|
|
|
|
|
foreach ($data as $key => $value) {
|
2009-12-10 12:25:38 +02:00
|
|
|
|
$aData[$aKv[$key]]=$value;
|
2009-07-26 16:43:16 +03:00
|
|
|
|
}
|
|
|
|
|
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;
|
2009-05-23 11:03:46 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2008-09-21 09:36:57 +03:00
|
|
|
|
/**
|
|
|
|
|
* Записать значение в кеш
|
|
|
|
|
*
|
2009-11-22 20:59:19 +02:00
|
|
|
|
* @param mixed $data
|
|
|
|
|
* @param string $sName
|
|
|
|
|
* @param array $aTags
|
|
|
|
|
* @param int $iTimeLife
|
2008-09-21 09:36:57 +03:00
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2009-07-26 16:43:16 +03:00
|
|
|
|
public function Set($data,$sName,$aTags=array(),$iTimeLife=false) {
|
2008-09-21 09:36:57 +03:00
|
|
|
|
if (!$this->bUseCache) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Т.к. название кеша может быть любым то предварительно хешируем имя кеша
|
|
|
|
|
*/
|
2009-08-19 17:53:16 +03:00
|
|
|
|
$sName=md5(Config::Get('sys.cache.prefix').$sName);
|
2009-04-27 22:57:43 +03:00
|
|
|
|
if ($this->sCacheType==SYS_CACHE_TYPE_FILE) {
|
|
|
|
|
$data=serialize($data);
|
|
|
|
|
}
|
2008-09-21 09:36:57 +03:00
|
|
|
|
return $this->oBackendCache->save($data,$sName,$aTags,$iTimeLife);
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Удаляет значение из кеша по ключу(имени)
|
|
|
|
|
*
|
|
|
|
|
* @param unknown_type $sName
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
public function Delete($sName) {
|
|
|
|
|
if (!$this->bUseCache) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Т.к. название кеша может быть любым то предварительно хешируем имя кеша
|
|
|
|
|
*/
|
2009-08-19 17:53:16 +03:00
|
|
|
|
$sName=md5(Config::Get('sys.cache.prefix').$sName);
|
2008-09-21 09:36:57 +03:00
|
|
|
|
return $this->oBackendCache->remove($sName);
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Чистит кеши
|
|
|
|
|
*
|
|
|
|
|
* @param void $cMode
|
|
|
|
|
* @param array $aTags
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
public function Clean($cMode = Zend_Cache::CLEANING_MODE_ALL, $aTags = array()) {
|
|
|
|
|
if (!$this->bUseCache) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return $this->oBackendCache->clean($cMode,$aTags);
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Статистика использования кеша
|
|
|
|
|
*
|
|
|
|
|
* @param unknown_type $iTime
|
|
|
|
|
* @param unknown_type $sMethod
|
|
|
|
|
*/
|
2009-07-26 16:43:16 +03:00
|
|
|
|
public function CalcStats($iTime,$sMethod) {
|
2008-09-21 09:36:57 +03:00
|
|
|
|
$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']++;
|
2009-11-22 20:59:19 +02:00
|
|
|
|
}
|
2008-09-21 09:36:57 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function GetStats() {
|
|
|
|
|
return $this->aStats;
|
|
|
|
|
}
|
2011-02-27 16:46:01 +02:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Сохраняет значение в кеше на время исполнения скрипта (некий аналог Registry)
|
|
|
|
|
*
|
|
|
|
|
* @param unknown_type $data
|
|
|
|
|
* @param unknown_type $sName
|
|
|
|
|
*/
|
|
|
|
|
public function SetLife($data,$sName) {
|
|
|
|
|
$this->aStoreLife[$sName]=$data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Получает значение из текущего кеша скрипта
|
|
|
|
|
*
|
|
|
|
|
* @param unknown_type $sName
|
|
|
|
|
* @return unknown
|
|
|
|
|
*/
|
|
|
|
|
public function GetLife($sName) {
|
|
|
|
|
if (key_exists($sName,$this->aStoreLife)) {
|
|
|
|
|
return $this->aStoreLife[$sName];
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2008-09-21 09:36:57 +03:00
|
|
|
|
}
|
|
|
|
|
?>
|