Statická metoda Cache vsude
- Scorpio
- Člen | 45
Zdravím,
chtěl bych se zeptat zda lze nějak jednoduše vytvořit statickou třídu pro
Cache kterou mohu zavolat kdekoliv. Něco jako třída pro dibi ta se jen
v configu nadefinuje a pak mi funguje úplně všude. Nemohl jsem tento návod
nikde najít. Nechci se ke cache pokaždé skoro v každé funkci připojovat.
Rad bych jen použil Cache::load() a Cache::save() a bylo by.
- David Matějka
- Moderator | 6445
storage bys nemel vytvaret, vyzaduj Nette\Caching\IStorage
jako
zavislost a cache si vytvor
- JDC
- Člen | 19
Nejlépe je si CacheStorage natahovat do služeb pomocí konstruktoru. Nette v DI obsahuje službu IStorage, což je vlastně ono „globální“ úložiště pro veškerou cache (složka temp).
public function __construct(Nette\Caching\Storages\IStorage $cacheStorage) {
$this->cache = new Cache($storage);
}
Tohle by měl být nejčistší způsob. Doporučuji si pro každou tvou cache ještě vytvářet namespace (To jsou ty jednotlivé složky začínající podtržítkem ‚_‘). Samozřejmně musíš mít onu službu zaregistrovanou v DI.
$this->cache = new Cache($storage, "mycache");
Když to chceš mít globálně ve více službách, předej si cache storage přes konstruktor v nějakém abstraktním předkovi. Přistupovat ke Cachi přes statickou třídu je hloupost, akorát tím znásilňuješ DI a celkem trošku riskuješ.
Editoval JDC (18. 6. 2014 21:53)
- Scorpio
- Člen | 45
Super toto je asi to řešení co jsem chtěl. Možná jsem se trochu blbě vyjádřil ale dejme tomu když mám vícero modelů a ve všech potřebuji pracovat se stejnou cache tak si ji při vytváření třídy identifikuji tím namespace a mohu s ní pracovat jak v presenterech tak v modelech. Ten malý řádek je více než snesitelný.
$cache = new Cache($storage,'namespace')
Poslední otázka zní jde to $storage nahradit nějakou globální konstantou abych vždy byl v tom „globaním“ úložišti?
- David Matějka
- Moderator | 6445
Co myslis „globalni“? Kdyz vyzadas IStorage, tak se vzdy bude pouzivat to storage, ktere je definovane v DI containeru, defaultne tedy FileStorage v temp slozce
- David Matějka
- Moderator | 6445
V neonu pouze onu modelovou tridu registrujes jako sluzbu. Kdyz budes mit v konstruktoru spravne typehint (jak uvadi JDC), tak se nette postara o autowiring
- Scorpio
- Člen | 45
Stale si moc nevím rady. Dle dokumentace jsem našel že v neonu si pomocí factory vytvořím toto:
cache:
parameters: [namespace]
class: Nette\Caching\Cache(Nette\Caching\Storages\FileStorage(%tempDir%),%namespace%)
Díky tomu budu mít funkci
$cache = ??->createCache($namespace)
Předpokladám že ještě něco musím udělat abych to mohl v presenterech popř v modelech volat jenže to už jsem v dokumentaci nenašel :(
- David Matějka
- Moderator | 6445
@Scorpio: kde to je v doc? to by se melo smazat ASAP :)
ok, tak uvedu priklad
class MyModelService
{
protected $cache;
public function __construct(Nette\Caching\IStorage $cacheStorage)
{
$this->cache = new Nette\Caching\Cache($cacheStorage, 'MyNamespace');
}
}
a to registrujes jako sluzbu
services:
- MyModelService
- Scorpio
- Člen | 45
Zde jsem to našel také je dost možné že jsem jen špatně pochopil to jak je to napsané https://doc.nette.org/cs/configuring#…
Edit: Děkuji za radu takto to asi fungovat bude jen ještě nevím přesně jak si to zavolam v presenteru ještě ještě sem se chtěl zeptat zda je možné si takhle jen vytvořit storage a samotnou cache spolu s unikatním namespace až později?
- David Matějka
- Moderator | 6445
V presenteru si tu sluzbu injectnes, mrkni na tenhle clanek https://doc.nette.org/…dependencies snad ti to pomuze. Ano, Cache nemusis vytvaret hned. Do property si proste uloz tu cacheStorage a cache si vytvor kdy chces
- JDC
- Člen | 19
Nemusíš. prostě si vytvoř abstrakního předka, tomu skrz konstruktor předej IStorage a tam si tu cache vytvoř. Pak od tohoto předka můžeš podědit další služby, ve kterých chceš cache používat.
abstract class BaseModel {
protected $cache;
public function __construct(Nette\Caching\Istorage $storage) {
$this->cache = new Cache($storage);
}
}
class AnotherModel extends BaseModel {
public function foo() {
$data = $this->cache->load("key");
...
$this->cache->save("key", $data);
}
}
Službu si pak zaregistruj v configu
services:
- AnotherModel
Službám nemusíš předávat žádné parametry. DI si to řeší samo a navíc už obsahuje službu IStorage, kterou představuje defaultní FileStorage
- Jan Endel
- Člen | 1016
@JDC Proč? Tohle rozhodně ne, kvůli cache si zavřít konstruktor a znemožnit dědění z dalších tříd, tohle je typický případ nadužívání dědičnosti. @Scorpio pokud neustále používáš cache nestandartním způsobem, tak si ji obal nějakou servicou co se ti o ni bude starat jak potřebuješ a vstřikuj si tu.
- Scorpio
- Člen | 45
Šlo by to tu uzavřít. Sem z toho ještě více zmatený než když jsem
začal. Pravděpodobně zůstanu u mého původního použití toto mi jen
zabralo týden času a k ničemu jsem se nedostal.
Myslel jsem že existuje nějaká jednoduchá metoda jako je u dibi která mi
zpřístupní funkci všude. Přijde mi divné pokaždé když chci používat
cache si určovat prostor a zakládat cache. Hlavně s tím prostorem je to
takový složitější když se snažím použít cache v nějakém php souboru
který je hluboko v adresářové struktuře tak pak musím složitě počítat
kolik adresářů nahoru a nedej bože kdybych daný php soubor přesunul.
- David Matějka
- Moderator | 6445
Pokud jsi zastancem statickeho pekla, prejdi na laravel :)
Tebe nezajima, jak jsi hluboko v adresarove strukture, jelikoz si cache storage vyzadas jako zavislost, jak uz tu bylo 100× psano. Pak muzes snadno vymenit implemnetaci cache storage a cachovat treba do redisu
Editoval matej21 (20. 6. 2014 13:40)