ImagePresenter – Image from db – Cache – Output – Browser cache
- Matey
- Člen | 142
ImagePresenter by sa mal starať o zobrazovanie obrázkov z databázy. Obrázky sú uložené v db ako MEDIUMBLOB. Každý obrázok sa cachuje na servery… potiaľto som problém nemal, ale ako správne nastaviť hlavičky pre prehliadač aby dokázal cachovať aj on to už mi chvíľu zabralo.
Nakoniec som to vyriešil a prehliadač si už obrázky cachuje.
Ale je to takto správne? jednak cachovanie a jednak ten spôsob akým chcem k obrázkom pristupovať
class ImagePresenter extends BasePresenter
{
/** @var Image */
private $image;
/** @var Container @inject */
public $container;
public function actionDefault($id) {
if (!$id) {
$this->error();
}
$cache = new Cache($this->container->cacheStorage, 'image');
$this->image = $cache->load($id) ? Image::fromString($cache->load($id)) : NULL;
if ($this->image === NULL) {
$image = $this->database->table('images')->get($id);
$this->image = Image::fromString($image->image);
$cache->save($id, $this->image->toString(), [Cache::EXPIRE => '14 days', Cache::SLIDING => TRUE]);
}
$time = new DateTime('2014-10-10 10:10:10'); // neskôr z db
$etag = md5(serialize($this->image));
$this->lastModified($time, $etag);
$this->getHttpResponse()->setExpiration('+ 14 days');
$this->getHttpResponse()->setHeader('Pragma', 'cache');
$this->image->send();
}
}
k tomu takáto routa v routeri:
$router[] = new Route('<presenter>/<id>.jpg', [
'presenter' => [
Route::FILTER_STRICT => TRUE,
Route::FILTER_TABLE => [
'image' => 'Image'
]
],
'action' => 'default',
'id' => NULL
]);
Editoval Matey (22. 11. 2014 11:58)
- Jan Suchánek
- Člen | 404
Ahoj já to řešil tak že presenter se volal vždy jen pokud se obrázek v filesystému nenašel a na hledání zda obrázek existuje jsem použil helper v latte.
Tzn.: Pokud obrázek neexistoval odkaz na obrázek vedl na presenter, který buď vrátil obrázek neexistuje nebo vyrobil veškeré náhledy které daný obrázek potřebude protože mu byla předána id a on už pak věděl komu obrázek patří.
Schéma mám jako upload (obsahuje veškeré údaje o obrázku včetně popisek a komu obrázek patří např. category, article, atd.) a upload_binary (jen odkaz na upload_id, data).
- Matey
- Člen | 142
Ak som dobre pochopil, tak data máš uložené v db ale všetky obrázky ukladáš na disk v klasickej podobe, ak obrázok nie je vygeneruješ ho.
Práve toho ukladania do klasickej podoby som sa chcel zbaviť, aby som sa o to nemusel starať a ešte sa aj eliminuje možnosť chyby spôsobenej napr pri neúspešnom mazaní.
Perfektne sa o to postará nette cache ktorá nahradí reálne obrázky. Ale obrázky musím znovu získavať zo stringu a následne $image->send(). Takto sa automaticky nevygenerujú všetky potrebné hlavičky pre browser cache, takže ich treba doplniť.
Tvoje riešenie je ale rýchlejšie (keď sa neberie v uvahu browser cachce) keďže obchádzaš requesty na nette a posielaš rálny obrázok z FS.
Budem vďačný za ďalšie názory, prípadne ukážky ako niečo takéto riešiť. Rád by som si toho prečítal viac, skôr ako ten moj ImagePresenter začnem používať.
Editoval Matey (13. 12. 2014 11:44)
- Jan Suchánek
- Člen | 404
Takhle, vše mám v db a o cache se nestarám, do db ukládám jen originál, samozřejmě do tabulky ukládám i jiné dokumenty (pdf, doc, xls …).
Obrázek nahraju formulářem do db
Uživatel i admin si až potom lazy přez prohlížeč vlastně sám přez presentera vygeneruje svůj náhled či velký obrázek.
O mazání se stará třída, která obrázky nahrává, jen vypne link na daný soubor a samozřejmě ho může zlikvidovat i na disku, je to podle mě lepší, navíc to umožňuje i obrázky pěkně pojmenovávat slugama a ukládat v jakékoliv adresářové struktuře.
Editoval jenicek (24. 11. 2014 13:58)