Берем 5ый друпал. Zend_Framework - кладем его в подкаталог library.
В $conf путь к ZF определяется так.
'filecache_zend_path' => 'library' . PATH_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . 'Azarov',
От ZF на самом деле надо очень мало - следующие файлы и каталоги:
Cache, Cache.php, Exception.php, Loader, Loader.php, Version.php
В комментариях описаны примерные конфигурационные параметры.
По умолчанию пользуется стандартный зендовский класс Zend_Cache_Backend_File.
У меня есть своя его версия чуть получше - чистка мусора в ней проводится раз в 5000 раз или как задашь и актуальность записей оценивается по своему.
По результатам тестирования - на 30% медленнее предыдущей модели. НО. Тут больше гибкости - учитывая заморочки 6го друпала - я буду развивать именно этот вариант
Вот такие пироги
Гибкость в следующем -можно подставлять бекенды кеша какие нравятся. Для APC, для мемкеша и тд.
Потом может разовью решение в сторону того что будет похоже на cacherouter. Вот такие дела.
*
* Filecache2 by Ilya V. "brainstorm" Azarov, brainstorm.name
* This module uses Zend framework cache to organize file cachig for drupal
*
* $conf configuration variables in settings.php
* $conf['filecache_zend_path'] - library path of zend framework
* by default 'library' . DIRECTORY_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . 'Azarov'
* $conf['filecache_maincacheclass'] = 'Zend_Cache_Backend_File' - main class for caching
* we use our class - Zend_Cache_Backend_Fastfile for caching
* Other advanced options would be later
* See _filecache2_params for defaults
*/
/*
* Wrapper for cache $conf parameters
*/
function _filecache2_params($param){
static $defaults;
if(!isset($defaults) ) $defaults = array(
'filecache_zend_path' => 'library' . PATH_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . 'Azarov',
'filecache_maincacheclass' => 'File', // Zend_Cache_Backend_File
'filecache_path' => 'files/cache',
'filecache_opts_Zend_Cache_Backend_File' => array(
'cache_dir' => null,
'file_locking' => true,
'hashed_directory_level' => 3,
'hashed_directory_umask' => 0755
),
// Zend_Cache_Backend_Fastfile
'filecache_opts_Fastfile' => array(
'cache_dir' => false, // say system - we need this option but it's auto
'file_locking' => true,
'cleaning_factor' => '5000', // evertime on couter is equal - make full clean
'hashed_directory_level' => 3,
'hashed_directory_umask' => 0755,
'file_name_prefix' => 'zc',
),
// Zend_Cache_Backend_File
'filecache_opts_File' => array(
'cache_dir' => false, // say system - we need this option but it's auto
'file_locking' => true,
'hashed_directory_level' => 3,
'hashed_directory_umask' => 0755,
'file_name_prefix' => 'zc',
)
);
global $conf;
if(isset($conf[$param] ) ) return $conf[$param];
elseif(isset($defaults[$param] ) ) return $defaults[$param];
return false;
}
function _filecache2_init_loaders(){
static $loaded;
if(!isset($loaded) ){
set_include_path(get_include_path() . PATH_SEPARATOR . _filecache2_params('filecache_zend_path') );
include_once('Zend/Loader.php');
Zend_Loader::registerAutoload();
$loaded = true;
}
}
function _filecache2_name_encode($cid){
return str_replace('=', '_', base64_encode($cid) );
}
function _filecache2_get_cache_object($table){
static $objects;
if(isset($objects[$table] ) ) return $objects[$table];
_filecache2_init_loaders();
// FOR FUTURE - make objects depending on per table configuration
$dirname = _filecache2_params('filecache_path') . DIRECTORY_SEPARATOR . $table;
if(!is_dir($dirname) ) mkdir($dirname, 0755, true);
$bopts = _filecache2_params('filecache_opts_' . _filecache2_params('filecache_maincacheclass') );
if(!$bopts) Zend_Cache::throwException('No options for ' . _filecache2_params('filecache_maincacheclass') );
if(isset($bopts['cache_dir'] ) ) $bopts['cache_dir'] = $dirname;
$cache = Zend_Cache::factory('Core', _filecache2_params('filecache_maincacheclass'),
array('caching' => true, 'lifetime' => null, 'automatic_cleaning_factor' => 0, 'ignore_user_abort' => true),
$bopts
);
$objects[$table] = $cache;
return $objects[$table];
}
function cache_get($cid, $table = 'cache') {
global $user;
// Garbage collection necessary when enforcing a minimum cache lifetime
$cache_flush = variable_get('cache_flush', 0);
if ($cache_flush && ($cache_flush + variable_get('cache_lifetime', 0) <= time())) {
_filecache2_get_cache_object($table)->clean(Zend_Cache::CLEANING_MODE_OLD);
variable_set('cache_flush', 0);
}
$mcid = _filecache2_name_encode($cid);
if($co = [user=unserialize]unserialize[/user](_filecache2_get_cache_object($table)->load($mcid) ) ){
return $co;
}
return 0;
}
function cache_set($cid, $table = 'cache', $data, $expire = CACHE_PERMANENT, $headers = NULL) {
// save($data, $id = null, $tags = array(), $specificLifetime = false)
$mcid = _filecache2_name_encode($cid);
$t = time();
$specificLifetime = false;
if($expire != CACHE_PERMANENT){
$t = $expire - $t;
if($t > 0) $specificLifetime = $t;
}
$o = new stdClass();
$o->data = $data;
$o->created = time();
$o->expire = $expire;
$o->headers = $headers;
$s = serialize($o);unset($o);
_filecache2_get_cache_object($table)->save($s, $mcid, array(), $specificLifetime);
}
function cache_clear_all($cid = NULL, $table = NULL, $wildcard = FALSE){
global $user;
if (!isset($cid) && !isset($table)) {
cache_clear_all(NULL, 'cache_page');
return;
}
if (empty($cid)) {
if (variable_get('cache_lifetime', 0)) {
// We store the time in the current user's $user->cache variable which
// will be saved into the sessions table by sess_write(). We then
// simulate that the cache was flushed for this user by not returning
// cached data that was cached before the timestamp.
$user->cache = time();
$cache_flush = variable_get('cache_flush', 0);
if ($cache_flush == 0) {
// This is the first request to clear the cache, start a timer.
variable_set('cache_flush', time());
}
else if (time() > ($cache_flush + variable_get('cache_lifetime', 0))) {
// Clear the cache for everyone, cache_flush_delay seconds have
// passed since the first request to clear the cache.
_filecache2_get_cache_object($table)->clean(Zend_Cache::CLEANING_MODE_OLD);
variable_set('cache_flush', 0);
}
}else{
// No minimum cache lifetime, flush all temporary cache entries now.
_filecache2_get_cache_object($table)->clean(Zend_Cache::CLEANING_MODE_ALL);
}
}else{
if ($wildcard) {
_filecache2_get_cache_object($table)->clean(Zend_Cache::CLEANING_MODE_ALL);
}else{
$mcid = _filecache2_name_encode($cid);
_filecache2_get_cache_object($table)->remove($mcid);
}
}
}
Комментарии
Спасибо, Илья, интересно!
в cache_set иногда передается $expire = CACHE_TEMPORARY эту ситуацию лучше обрабатывать отдельно...
CACHE_TEMPORARY - обычно складываются в отдельные таблицы и функция та же что и у CACHE_PERMANENT, так что в данной конфигурации модуль для 5ки достаточен
Для 6ки в процессе - и там уже думать сильно надо на тему очисток кеша меню и форм... дело ближайших двух недель...
вышел 6.3 кеш форм поправлен - можно двигаться
терпение. все будет.
Как я посмотрю, модуль уже продается вовсю. Кто нибудь пробовал уже?
не продается.
я приостановил это дело. есть свой класс кеша - его я пока не раздаю.
а модуль выложен и объснено как поставить.