Nette\Image a ztracená obrazová data při cachování
- honza.kopecky
- Člen | 2
Ahoj,
mám třídu Contact, jejíž atribut ProfilePhoto je typu Nette\Utils\Image.
Pole objektů Contact získávám pomocí parsování XML a výsledky si
kešuji. Problém je, že při serializaci je výstupem atributu ProfilePhoto
toto: O:17:"Nette\\Utils\\Image":1:{s:24:"\x00Nette\\Utils\\Image\x00image";i:0;}
Ano, zkontroloval jsem, zda atribut opravdu není prázdný a není. Před
serializací je v proměnné image (objektu Image) uložen gd resource. Zdá se
ale, že během serializace tohle úplně zmizí a data obrázku se ztratí. Pro
kešování používám klasickou notaci $cache->save()
na
objekty typu Contact. Všechny ostatní atributy (včetně vnořených objektů)
fungují bez problémů, problém se projevuje jen u Image.
Koukal jsem do zdrojových kódů třídy Nette\Utils\Image a nevšiml jsem si, že by někde byla serializace definovaná. Znamená to, že tato třída serializaci nepodporuje a je třeba ji rozšířit? Existuje už někde hotové řešení?
Předem díky za odpověď.
- Jan Tvrdík
- Nette guru | 2595
mám třídu Contact, jejíž atribut ProfilePhoto je typu Nette\Utils\Image
To vypadá jako velmi špatný nápad. Obrázek patří na disk / na S3. GD image struktura je vhodná akorát na zpracování obrázku, ne na jejich dlouhodobé uchovávání.
- honza.kopecky
- Člen | 2
Asi to nebude úplně nejlepší řešení, ale když už data kešuji na disk, tak mi to nepřipadá až takový rozdíl, jestli ten obrázek budu mít v odděleném souboru nebo společně s objektem. Obzvlášť pokud vezmu v potaz tu práci, kterou mi to šetří.
Každopádně jsem to vyřešil poděděním třídy Nette\Utils\Image následovně:
use Nette\Utils\Image;
class SerializableImage extends Image implements \Serializable
{
public function serialize()
{
return \serialize(['data' => (string)$this]);
}
public function unserialize($serialized)
{
$unserializedArray = \unserialize($serialized);
$this->setImageResource((SerializableImage::fromString($unserializedArray['data']))->getImageResource());
}
}
- Jan Tvrdík
- Nette guru | 2595
když už data kešuji na disk, tak mi to nepřipadá až takový rozdíl, jestli ten obrázek budu mít v odděleném souboru nebo společně s objektem
Je to obrovský rozdíl, co se spotřebované paměti a CPU týče. Kešuješ, abys šetřil výkon, ale implementoval jsi to způsobem, který je extrémně (!) neefektivní.