EN | CS | Přihlásit | Registrovat

Nette\Caching

Knihovna sloužící k ukládání dat do keše.

Příklad použití:

// získání instance cache
$storage = new FileStorage('tmp');
$cache = new Cache($storage); // nebo $cache = Environment::getCache()

// zápis do cache
$cache['data'] = $myData;

// čtení z cache
$cachedData = $cache['data'];

// mazání z cache
unset($cache['data']);
// nebo
$cache['data'] = NULL;

// ověření, zda je položka v keši
if (isset($cache['data'])) ...
// nebo
$cachedData = $cache['data'];
if ($cachedData !== NULL) ...

Do keše lze ukládat jakékoliv struktury, nemusí to být jen řetězec.

Takže taková jednoduchá implementace by mohla vypadat třeba takto:

if (isset($cache['template'])) {
$template = $cache['template'];
} else {
$template = sloziteGenerovani();
$cache['template'] = $template;
}

echo $template;

Ale to není zdaleka vše. Při ukládání položek lze specifikovat několik dalších parametrů a podmínek pro invalidaci. Protože v případě přiřazení $cache['key'] = $data není kde tyto podmínky specifikovat, použijeme pro ukládání obsahu funkci $cache->save($key, $data, $options). Parametr $options je pole, které může mít tyto klíče:

expire => (int) čas, kdy obsah vyexpiruje
sliding => (bool) má se expirace prodlužovat?
files => (array) seznam souborů, na kterých cache závisí
items => (array) seznam klíčů v keši, na kterých tato položka závisí
tags => (array) seznam vlastních tagů
priority => (int) priorita
consts => (array) seznam konstant, na kterých cache závisí

Když nějaká položka vyexpiruje, pak vyexpiruje celá cache. Garbage collector ji poté fyzicky odstraní z disku.

Příklad použití:

Cache vyexpiruje za 10 min:

$cache->save($key, $value, array(
'expire' => time() + 60 * 10,
));

Cache vyexpiruje za 10 min. Pokud v té době bude načtena, expirace se prodlouží na dalších deset minut.

$cache->save($key, $value, array(
'expire' => time() + 60 * 10,
'sliding' => TRUE,
));

Cache vyexpiruje v okamžiku, kdy se změní kterýkoliv z uvedených souborů (pro bezproblémovou funkčnost je třeba používat absolutní cesty). V praxi to používám třeba pro kešování konfigurace nebo šablon – jakmile se příslušný soubor změní, Nette automaticky invaliduje i keš.

$cache->save($key, $value, array(
'files' => array('template.phtml', 'config.ini'),
));

Cache je závislá na jiných položkách v keši – vyexpiruje v okamžiku, kdy se změní položky s klíčem ‚key1‘ nebo ‚key2‘. To lze využít tehdy, když kešujeme třeba www stránku a pod jinými klíči její části. Jakmile se část změní, invaliduje se celá stránka.

$cache->save('key3', $value, array(
'items' => array('key1', 'key2'),
));

Položce můžeme přiřadit seznam vlastní tagů. To lze použít třeba tehdy, pokud kešujeme www stránku, kde je článek + komentáře. Jakmile se článek změní, nebo jakmile se objeví nový komentář, necháme vyexpirovat všechny položky s příslušným tagem:

$cache->save($key, $value, array(
'tags' => array('clanek#10', 'komentare#10'),
));

// vyexpirujeme všechny položky s tagem 'komentare#10':
$cache->clean(array(
'tags' => array('komentare#10'),
));

Nakonec je tam položka priorita, podle které lze cache čistit:

$cache->save($key, $value, array(
'priority' => 50,
));

// smažeme všechny položky s prioritou rovnou nebo menší 100:
$cache->clean(array(
'priority' => 100,
));

Všechny parametry lze navzájem kombinovat.

V rámci jednoho sezení má Nette načetlou cache i v paměti. Zavolání funkce $cache->release() uvolní tyto zdroje z paměti.

Invaliduji-li tag funkcí $cache->clean(), pak se smaže z keše vše s tímto tagem. U velmi velkých aplikací, kde mohou být na serveru tisíce kešovaných souborů by se musel prohledávat celý adresář, který kěš drží a to by mohlo být systémově pomalé. Jako řešení se nabízí implementace na databázi, nebo také při kešování nastavovat prioritu.

$cache->save($key, $value, array(
Cache::TAGS => array('blog/10', 'comments/10', 'novinky'),
Cache::PRIORITY => 2,
));

$cache->clean(array(Cache::TAGS => 'blog/10'));

V Nette\Environment lze na práci s cache zaregistrovat službu, pokud si chcete objekt pro práci s keší přepsat, jediný požadavek je, aby implementovalo rozhraní ICacheStorage. V případě, že se rozhodnete změnit způsob zpracování keše v úložišti, můžete využít připraveného objektu DummyStorage, což je úložiště, které ve skutečnosti nic nedělá. Také je zde i podpora pro MemCache kterou obstarává objekt MemcachedStorage.

Viz také:


Komentáře Comments feed

michal.vrabel | 7. 4. 2010, 14:31 | question

Volanie $cache = new Cache; mi nefunguje hlási Argument 1 passed to Cache::__construc­t() must be an instance of ICacheStorage, none given, called in … čo mi vlastne pripadá logické lebo v triede Cache je __construct(I­CacheStorage $storage, $namespace = NULL)

Pri Environment::get­Cache() je return new Cache(self::get­Service(„Nette\Cachin­g\ICacheStora­ge“),$namespa­ce); čo aj funguje.

Tak ako je to s tým $cache = new Cache; ???

Jan Tvrdík | 7. 4. 2010, 18:19 | comment

Konstruktor třídy Cache skutečně vyžaduje jako parametr instanci ICacheStorage. V dokumentaci jsem to opravil, díky za upozornění.

Login to submit a comment