Nody (Dynamické routy)
- Patrik Votoček
- Člen | 2221
Už nějáký čas přemýšlím nad tím jak „správně“ vyřešit nody (dynamické routy). Mám v hlavě pár nápadu jak by to šlo ale nepříjdou mě správné. Nicméně je tady popíšu.
- Je dynamické načtení (z DB/cache) a předat je routeru. Ale nepříjde mě správné mít pak v aplikaci třeba 500 rout. (Asi by jí to zpomalilo)
- Napsat router který by si sám šahal do DB (cache) a podle toho načetl moduly/presenter. Taky se mě to moc nepozdává.
Pokud nevíte o co mě de a proč to potřebuju řešit tak se to teď pokusím popsat. Jde o to že zákazník/uživatel aplikace by chtěl na web vložit článek a pak další galerii. Článek by chtěl mít s URL example.com/nejaky-muj-clanek a example.com/nejaka-moje-galerie . Jenomže já jako tvůjce aplikace dopředu nevím jak on to bude chtít. A taky mám od zákazníka/uživatele odezvu že nechce mít URL ve tvaru example.com/clanek/nejaky-muj-clanek resp. example.com/galerie/nejaka-moje-galerie . A tak řeším tuto otázku.
Jak to řešíte? Nebo jak by jste to řešily?
- Mas3r
- Člen | 116
Já jsem to vyřešil přes návrh 2. Stačí si napsat vlastní router.
Všechny routy uložíš do Cache. Trošku problémů je s vytvářením nodů ve stromových strukturách, ale třeba to nebudeš potřebovat.
Stačí upravit pak matchUrl a constructUrl.
V DB to ukládám:
notebooky/podle-hmotnosti/do-3kg ⇒ Eshop:Catalog:View:45
- Patrik Votoček
- Člen | 2221
Mas3r napsal(a):
… Trošku problémů je s vytvářením nodů ve stromových strukturách, ale třeba to nebudeš potřebovat…
Jakej problém myslíš?
Když už řeším nody tak počítám i se stromovou strukturou.
- Patrik Votoček
- Člen | 2221
Taky si myslím stačí pouze spustit dávku na přejmenování všech Nodu které obsahují to co chceš změnit nebo pokud to máš řešené tak že máš uloženou strukturu takto:
notebooky - kategoriepodle-hmotnosti - filtr
do-3kg - parametr filtru
tak nikde není psáno že musíš mít jednotlivé další parametry uloženyjako
notebooky/podle-hmotnosti/do-1kgnotebooky/podle-hmotnosti/do-2kg
notebooky/podle-hmotnosti/do-3kg
notebooky/podle-hmotnosti/do-4kg
notebooky/podle-hmotnosti/do-5kg
ale můžeš je mít uloženy jako
notebooky - #1podle-hmotnostri - #2 - parrent #1
do-1kg - #3 - parrent #2
...
do-5kg - #n - parrent #2
a pak když změníš notebooky za netbooky tak se to automaticky promítne
až do do-3kg…
# je bráno jako identifikátor (id)
- kravčo
- Člen | 721
Ja by som s routovaním nevymýšľal, spravil by som jednu routu
Node:view?path=notebooky/do-20kg/armadne
Cieľový prezenter môže cestu sparsovať a prípadne forwardovať na iné prezentery/akcie…
Priložím ešte Davidov príklad vlastného routra (ak by ste chceli ísť tou cestou)
- Honza Marek
- Člen | 1664
Já jsem si vyrobil něco takového:
<?php
// pseudokód
class ArticleRouter {
private $data;
function __construct() {
$arr = dibi::query("select id, url, parent from articles")->fetchAssoc("parent,#");
$this->addArticlesWithParent(NULL, "", $arr);
}
function addArticlesWithParent($parentId, $startUrl, $articles) {
// rekurzivně nacpat do pole $data
foreach ($articles[$parentId] as $item) {
$this->data[$item->id] = $startUrl . "/" . $item->url;
$this->addArticlesWithParent($item->id, $startUrl . "/" . $item->url, $articles);
}
}
function match(IHttpRequest $context) {
// jestli je v poli $data, tak přidat do parametrů presenteru id
}
function constructUrl(PresenterRequest $request, IHttpRequest $context) {
// if isset($data[$params["id"]) return $data[$params["id"]];
}
}
?>
Nechce se mi to víc rozepisovat, snad je princip jasný. Myslím, že pro menší a střední weby je to dobré. Pro větší nevím, jestli je dobré přednačíst adresu tisíce článků.
- David Grudl
- Nette Core | 8218
vrtak-cz napsal(a):
- Je dynamické načtení (z DB/cache) a předat je routeru. Ale nepříjde mě správné mít pak v aplikaci třeba 500 rout. (Asi by jí to zpomalilo)
Spíš bych řekl zabilo ;)
- Patrik Votoček
- Člen | 2221
Tak mě to nedalo a vydal jsem se to testovat…
Testovací aplikace
- 10000 Nodu/Rout (+1 univerzální na všechno, co neprojde)
- 1 Presenter:action – pouze načetl z DB (vždy sahal do DB) testovací text a vyrendroval ho společně s ID Nody/Routy. Text se tahal vždy stejný, tzn. z tabulky data na s id 1.
- Testování času běhu celé app od načtení Nette\loader po rendering (stopky se stoply až při samotném renderování) – All
- Testování času běhu od zavolání $application->run() po spuštění akce v presenteru ({Presenter}Presenter::action{Action}) – Router
Co se testovalo
- možnost uvedená výše pod číslem 1
- pouze z DB
- cache
- možnost uvedená výše pod číslem 2
- pouze z DB
- cache
X | 1a | 1b | 2a | 2b |
---|---|---|---|---|
All | 1.2992276748 | 1.25103594859 | 0.03462378184 | 0.0349680980047 |
Router | 0.471882522106 | 0.468844731648 | 0.00418408711751 | 0.00432453552882 |
Časy jsou průměrné, po otestování 100 různých url (prvních 10 záznamů + posledních 10 záznamů + prostředních 10 záznamů + 70 náhodných) – vždy se jednalo o stejný seznam (tzn. 1a byla testována na stejné url, jako ostatní – 1b, 2a, 2b). Jsou uvedeny v sekundách.
Z uvedené tabulky vyplývá, že možnost 2a je 37.5x rychlejší, pokud se týká celé aplikace a 112x rychlejší, pokud se týká routeru, než možnost 1a. U možnosti 2b vs. 1b je to 35x aplikace a 108x router. Jak je taky patrné s cache a bez ní, jsou rozdíly zanedbatelné. Nicméně tento test nebyl prováděn na produkčním prostředí za ostrého provozu, takže mohou být některé výsledky zkreslené. Se zapnutou cache by měly být aplikace rychlejší, než bez ní.
- David Grudl
- Nette Core | 8218
Ještě by to chtělo, aby se při renderování zobrazilo tak 50 různých odkazů na jiné nody.
- Patrik Votoček
- Člen | 2221
Až se budu po fotbale nudit tak na to kouknu… ale myslím že se to moc lišit nebude… :-)