Statická metoda Cache vsude

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Scorpio
Člen | 45
+
0
-

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.

mkoubik
Člen | 728
+
+11
-

Ano, jde to, ale později toho budeš litovat.

Scorpio
Člen | 45
+
0
-

Tak to teď moc nechápu. Co to způsobí ja měl za to že mi to hodně ulehčí práci. Když mam jeden model a v několika medodách potřebuju stejnou cache tak se k ni musím vždy připojovat natavovat prostor atd atd., ale rád se přiučím co mi to může způsobovat když to bude statické?

Aurielle
Člen | 1281
+
0
-

Nebudeš moct tvoji Cache snadno vyměnit, tudíž třeba pro účely testů nebo když se rozhodneš změnit vnitřní implementaci / přejdeš na jiný cache systém, …

Scorpio
Člen | 45
+
0
-

No ok a je šance alespoň globalně nastavit storage?

$storage = new Nette\Caching\Storages\FileStorage('../temp/cache');
$cache = new Cache($storage);

Nelíbí se mi že musím na začátku každé metody psát tohle zvlast když to pak vnořím do další složky musím upravovat cesty.

David Matějka
Moderator | 6445
+
0
-

storage bys nemel vytvaret, vyzaduj Nette\Caching\IStorage jako zavislost a cache si vytvor

JDC
Člen | 19
+
+3
-

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
+
0
-

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
+
0
-

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

Scorpio
Člen | 45
+
0
-

Řeknu to takto. Nejsem moc zběhlý v tom co napsat do config.neon aby mi to fungovalo. Prosím mohl by mi někdo poradit konkretně?

David Matějka
Moderator | 6445
+
0
-

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
+
0
-

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
+
0
-

@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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

@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
+
0
-

Š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
+
0
-

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)