Před nějakou dobou jsem na La Trine zprovoznil zobrazování avatarů u komentářů. Využívám služeb serveru Gravatar, kde se můžete zaregistrovat a nahrát si vlastní ikonku. Pak už jen stačí při komentování zadat odpovídající e-mailovou adresu.
Odezva serveru Gravatar docela kolísá a stahování avatarů značně brzdí prohlížeč. Rozhodl jsem se naprogramovat nástroj, který by obrázky ukládal do cache přímo na serveru dgx.cz. Snahou bylo vytvořit co nejrychlejší a kratičký kód, který nerozhodí ani výpadek Gravataru. Nijak jsem neřešil zamykání souborů a atomicitu (nejde o kritická data).
// Cache for gravatar.com by dgx
// config
$gravatarURI = 'http://www.gravatar.com/avatar.php';
$cacheDir = dirname(__FILE__);
$expiration = 60*60*24*2; // 2 days
$emptyGIF = "GIF89a\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;";
// check parameters (sanitize forbidden chars + dot)
$query = @$_SERVER['QUERY_STRING'];
$query = preg_replace('#[\x00-\x1F"*/:<>?\\\\|.]#', '', $query);
if (!$query) exit;
// is avatar cached?
$cacheFile = $cacheDir.'/'.$query;
$isCached = is_file($cacheFile);
$isExpired = $isCached && (time() - filemtime($cacheFile) > $expiration);
$img = null;
if (!$isCached || $isExpired)
{
// download avatar
$img = @file_get_contents($gravatarURI.'?'.$query);
// put into cache
if ($img != null) {
file_put_contents($cacheFile, $img);
}
// for PHP4 use: fwrite(fopen($cacheFile, 'wb'), $img);
}
// load from cache or empty GIF
if ($img == null) {
$img = $isCached ? file_get_contents($cacheFile) : $emptyGIF;
}
// send cache header
header("Cache-Control: max-age=$expiration");
// detect correct mimetype
if ($img[1] == 'P') {
header('Content-Type: image/png');
} elseif ($img[1] == 'I') {
header('Content-Type: image/gif');
} else {
header('Content-Type: image/jpeg');
}
// send image
echo $img;
Ještě komentář: $emptyGIF
se použije tehdy, pokud server
gravataru neodpovídá. V kódu nejsou testovány hlavičky, neskládám
žádné URL a mimetyp zjišťuji snad nejrychlejším možným způsobem.
Návod k použití
Skript umístíte do adresáře s právem zápisu a volání původní služby změníte na volání tohoto skriptu. Změní se tedy pouze URI, nic víc.
Technika je do jisté míry univerzální, můžete s drobnými úpravami kešovat i jiná data.
Komentáře
error414 #1
tohle jsem chtel uz jednou napsat ale nybeylo dostatek casu. Jsem rad ze se stim popral nekdo jiny.
louix #2
Nádhera, tohle se mi zdá jako dost dobře využitelý kousek PHP kódu, takže to asi na mým webu použiju (-:
Martin Grames #3
Díky za skript.
Vzhledem k tomu, že funkce file_get_contents a file_put_contents nepodporuje můj hosting, tak jsem si je vyhledal/napsal následovně:
David Grudl #4
#3 Martine Gramesi, v podstatě by stačilo místo
file_put_contents
(existuje od PHP 5) napsatDal jsem to do poznámky do zdrojáku.
file_get_contents
by mělo fungovat od PHP 4.3.0, která byla vydaná už v roce 2002.Martin Grames #5
#4 Davide Grudle, Problém je v tom, že mám na hostingu zakázáno url file access, takže nemůžu používat file_get_contents() ani fopen pro externí skripty (soubory) ☹
error414 #6
#5 Martine Gramesi, tak to je nacase zmenit hosting, ne?
David Grudl #7
Celá věc by se dala ještě doplnit o podporu hlavičky
If-Modified-Since
, kterou gravatar.com podporuje, ale vzhledem k průměrné velikosti avataru 700 bajtů je to jedno.Mayo #8
Nič rozumné teraz nenapíšem, len to chcem vyskúšať. Dúfam, že emailová adresa, ktorú treba zadať je tá pod ktorou som si registroval avatar a nie nejaká špeciálna – vygenerovaná gravatar-om. Tento môj avatar bol pôvodne vytvorený pre last.fm, ale tentokrát som ho neokresal treshold-om. Ešte raz sorry za tento blábol…
Roj #9
Mne to nefacha, asi se jeste nestihlo nic nakesovat 🙂
David Grudl #10
#9 Roji, naopak, stihlo se nakešovat, že avatar nepoužíváš. A protože expirace je nastavena na 48 hodin, tak zatím není vidět.
(no že jsi to ty, tak jsem učinil výjimku nejvýjimkovatější a smazal cache 🙂 )
Roj #11
Prázdná keš, taky keš! 🙂
xom #12
Děkuji za pěkný nápad, na podzim budu chtít gravatary u sebe také pustit.. (tato zpráva je vlastně pokusem, jak ten můj vypadá.. ;o))
Petr #13
Jak je to s rychlostí u curl a file get contents ?
wosa #14
Moc díky za tenhl skript, doufám, že ho začne používat co nejvíc blogů.
Jirka #15
Díky za script – využiju 🙂
Jiří Bureš #16
Žádná lest. Jen test.
koty #17
Tak to taky vyzkouším, jak svůj nový gravatar, tak kód.
mZk #18
Nevidím tam proměnou mail. Jak to funguje? U sebe na webu to mám řešené přes:
` $grav_url = „http://www.gravatar.com/avatar/“.md5($email). ` a pak mám ` img src grav_url… `
mZk #19
Tak už jsem pochopil, že je to jako parametr. Ale stále to nejde. Hází mí to 43B velké soubory. Jako parametr má být ten hash? Třeba 68c2afc934fa66f3fde28b9639ef8632? Nebo co má být jako parametr?
mZk #20
sry, už vím 🙂 problém byl v avataru, nebyl zrovna dostupný tak to nefakalo (nemohlo to kešovat).. dobrej script
jenda.69 #21
Ahoj, já se fakt omlouvam za lamí otázku, v php umim fakt jenom málo.
Chtěl bych se zeptat: jak to mam udělat, aby se mi neukázal vůbec žádnej obrázek, pokud ten uživatel nemá gravatar?
Dal jsem si na stránky ten kód, co je nahoře, ale když uživatel gravatar nemá, tak se mi ukáže taková hnusná modrá ikona gravatar. Já bych raději chtěl, aby to v tom případě vůbec nedávalo do kódu ani ten tag „img“ s tim „žádným“ gravatarem (jako je to tady, pokud správně koukám). Díky za odpověď.
BaRacuda #22
Díky za tip!
zirafka #23
#21 jenda.69, nedavno jsem resila to stejne… bohuzel jsem to zjistovala v dobe, kdy gravatar.com nejel, takze jsem nenasla, jestli to jde udelat nejak, aby nevracel zadnou ikonku, ale urcite si muzes nastavit default obrazek, ktery ti bude vracet (napriklad pruhledny 1×1px GIF, tak jak to ma tento blog.)
Staci za URL pridat:
&default=http%3A%2F%2Fwww.example.com%2Fsomeimage.jpg
viz. http://site.gravatar.com/site/implement#…
Jinak mam podezreni, ze dgx to tu ma stejne udelane uz davno jinak, protoze to napriklad bere i ikonky z nekdo.bloguje.cz/blogavatar.png
jenda.69 #24
#23 zirafko, Nakonec jsem to udělal tak, jak píšeš ty…
No a avatar jsem si nahrával v sobotu k večeru a ještě teď v pondělí odpoledne ho nemam. :(
Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.