Прежде всего, перестало работать свойство cache_handler. Теперь свой кэшер подключается так:
PHP
$smarty->caching_type='memcache';
При этом smarty ищет в каталогах с плагинами файл cacheresource.memcache.php, а внутри него ожидает увидеть класс Smarty_CacheResource_Memcache.
Указанный класс должен иметь следующие методы:
getCachedTimestamp
getCachedFilepath (в случае, если включено cache_modified_check)
getCachedContents
writeCachedContent
clearAll
clear
Так как за наличием файлов кэша следит сам memcache, а фалов у нас никаких нет, то опцию cache_modified_check сразу отключаем:
PHP
$smarty->caching_type='memcache';
$smarty->cache_modified_check=false;
при этом, понятное дело, метод getCachedFilepath становится не нужен.
Определение времени сохранения кэша можно либо эмулировать (memcache все равно сам следит за его актуальностью) или сохранить его в memcache вместе с контентом. Я пока что выбрал второй вариант.
Ну и еще один неприятный момент - в качестве кэша сохраняется не html, а php код, которые после загрузки необходимо выполнить.
В итоге класс выглядит примерно так:
PHP
class Smarty_CacheResource_Memcache {
function __construct($smarty)
{
$this->smarty = $smarty;
$this->_cacher = new Cache_Memcache(
LabConfig::$cfg["memcached_host"],
LabConfig::$cfg["memcached_port"],
LabConfig::$cfg["memcached_compress"]);
}
public function getCachedTimestamp($obj)
{
$cache_id=$this->getCacheId($obj);
if ($this->_result[$cache_id]['timestamp'])
return $this->_result[$cache_id]['timestamp'];
if ($result=$this->_cacher->get($cache_id))
{
//так как кэш все равно понадобится
//сразу его помещаем в свойства объекта
$this->_result[$cache_id]=unserialize($result);
if ($this->_result[$cache_id]['timestamp'])
return $this->_result[$cache_id]['timestamp'];
}
return false;
}
public function getCacheId($_template)
{
if (!$this->cache_id)
$this->cache_id=md5($_template->template_resource
.$_template->cache_id
.$_template->compile_id);
return $this->cache_id;
}
public function getCachedContents($_template, $no_render = false)
{
if (!$no_render)
{
ob_start();
}
$_smarty_tpl = $_template;
$cache_id=$this->getCacheId($_template);
if (isset($this->_result[$cache_id]['content']))
{
$result=$this->_result[$cache_id]['content'];
}
elseif($result=$this->_cacher->get($cache_id))
{
$result=unserialize($result);
if (isset($result['content']))
$result=$result['content'];
}
//в переменной содержится php код,
//который необходимо выполнить
eval('?'.'>'.$result);
if ($no_render)
{
return null;
}
else
{
return ob_get_clean();
}
return null;
}
public function writeCachedContent($_template, $content)
{
if (!$_template->resource_object->isEvaluated)
{
//создаем суррогатный ключ timestamp
//можно обойтись без него, но при этом
//логика кода станет менее очевидной
$content=serialize(array('timestamp'=>time(),
'content'=>$content));
$this->_cacher->save($content,
$this->getCacheId($_template),
$_template->cache_lifetime);
return true;
}
return false;
}
public function clearAll()
{
return $this->_cacher->clean();
}
public function clear($resource_name, $cache_id, $compile_id)
{
return $this->_cacher->remove(md5($resource_name
.$cache_id.$compile_id));
}
}