Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Translate to English… Ins Deutsche übersetzen…

Kešování avatarů z gravatar.com

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.

napsáno 10. 8. 2006 | shlédnuto 9655x | nahoru


Komentáře RSS 2.0 komentářů » přidat

#1 error414 nový

tohle jsem chtel uz jednou napsat ale nybeylo dostatek casu. Jsem rad ze se stim popral nekdo jiny.

Posláno 10. 8. 2006 v 19.48 | Odpovědět
avatar

#2 louix http://www.deaddream.net/ nový

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 (-:

Posláno 10. 8. 2006 ve 21.15 | Odpovědět
avatar

#3 Martin Grames http://www.chapadlo.cz nový

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ě:

define('FILE_APPEND', 1);
function file_put_contents1($n, $d, $flag = false) {
   $mode = ($flag == FILE_APPEND || strtoupper($flag) == 'FILE_APPEND') ? 'a' : 'w';
   $f = @fopen($n, $mode);
   if ($f === false) {
       return 0;
   } else {
       if (is_array($d)) $d = implode($d);
       $bytes_written = fwrite($f, $d);
       fclose($f);
       return $bytes_written;
   }
}
// načtení gravataru ze serveru
function file_get_contents1($f) {
  $ch = curl_init();
  curl_setopt ($ch, CURLOPT_URL, $f);
  curl_setopt ($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  $soubor = curl_exec($ch);
  curl_close ($ch);
  return $soubor;
}
// načtení gravataru z cache
function file_get_contents2($f) {
  return join ('', file ($f));
}
Posláno 10. 8. 2006 ve 21.37 | Odpovědět
Na komentář reagoval [4] David Grudl
avatar

#4 David Grudl http://davidgrudl.com nový

#3 Martin Grames: v podstatě by stačilo místo file_put_contents (existuje od PHP 5) napsat

fwrite(fopen($cacheFile, 'wb'), $img);

Dal 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.

Posláno 10. 8. 2006 ve 21.42 | Odpovědět
Na komentář reagoval [5] Martin Grames
avatar

#5 Martin Grames http://www.chapadlo.cz nový

#4 David Grudl: 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) :-(

Posláno 10. 8. 2006 ve 21.55 | Odpovědět
Na komentář reagoval [6] error414

#6 error414 nový

#5 Martin Grames: tak to je nacase zmenit hosting, ne?

Posláno 10. 8. 2006 ve 21.58 | Odpovědět
avatar

#7 David Grudl http://davidgrudl.com nový

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.

Posláno 10. 8. 2006 ve 22.12 | Odpovědět
avatar

#8 Mayo nový

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…

Posláno 10. 8. 2006 ve 23.51 | Odpovědět
avatar

#9 Roj http://roj.bloguje.cz nový

Mne to nefacha, asi se jeste nestihlo nic nakesovat :-)

Posláno 11. 8. 2006 v 10.20 | Odpovědět
Na komentář reagoval [10] David Grudl
avatar

#10 David Grudl http://davidgrudl.com nový

#9 Roj: 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 :-) )

Posláno 11. 8. 2006 ve 14.03 | Odpovědět
avatar

#11 Roj http://roj.bloguje.cz nový

Prázdná keš, taky keš! :-)

Posláno 11. 8. 2006 ve 14.05 | Odpovědět
avatar

#12 xom http://pinion.xom-tom.com nový

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))

Posláno 11. 8. 2006 ve 23.42 | Odpovědět

#13 Petr http://melodie.na-mobil.cz nový

Jak je to s rychlostí u curl a file get contents ?

Posláno 13. 8. 2006 ve 13.07 | Odpovědět
avatar

#14 wosa http://operacesky.net/ nový

Moc díky za tenhl skript, doufám, že ho začne používat co nejvíc blogů.

Posláno 13. 8. 2006 v 19.33 | Odpovědět
avatar

#15 Jirka nový

Díky za script – využiju :-)

Posláno 15. 8. 2006 v 15.36 | Odpovědět
avatar

#16 Jiří Bureš http://blog.converter.cz/ nový

Žádná lest. Jen test.

Posláno 27. 8. 2006 v 17.40 | Odpovědět
avatar

#17 koty nový

Tak to taky vyzkouším, jak svůj nový gravatar, tak kód.

Posláno 1. 9. 2006 v 16.24 | Odpovědět
avatar

#18 mZk http://mozektevidi.ic.cz nový

Nevidím tam proměnou mail. Jak to funguje? U sebe na webu to mám řešené přes:
` $grav_url = „http://www.gra­vatar.com/ava­tar.php?grava­tar_id=“.md5($e­mail). ` a pak mám ` img src grav_url… `

Posláno 20. 9. 2006 v 17.19 | Odpovědět
avatar

#19 mZk http://mozektevidi.ic.cz nový

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 68c2afc934fa66f3fd­e28b9639ef8632? Nebo co má být jako parametr?

Posláno 20. 9. 2006 v 19.03 | Odpovědět
avatar

#20 mZk http://mozektevidi.ic.cz nový

sry, už vím :-) problém byl v avataru, nebyl zrovna dostupný tak to nefakalo (nemohlo to kešovat).. dobrej script

Posláno 20. 9. 2006 ve 21.10 | Odpovědět
avatar

#21 jenda.69 http://www.jendamusic.net nový

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ěď.

Posláno 17. 2. 2007 ve 20.31 | Odpovědět
Na komentář reagoval [23] zirafka
avatar

#22 BaRacuda http://barablog.dewtex.net nový

Díky za tip!

Posláno 19. 2. 2007 v 8.08 | Odpovědět
avatar

#23 zirafka http://blog.zirafka.cz nový

#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.blogu­je.cz/blogava­tar.png

Posláno 19. 2. 2007 ve 12.28 | Odpovědět
Na komentář reagoval [24] jenda.69
avatar

#24 jenda.69 http://www.jendamusic.net nový

#23 zirafka: 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. :(

Posláno 19. 2. 2007 v 15.57 | Odpovědět

Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.

Výtah na začátek článku na první komentář

Názory čtenářů v diskusích nejsou názory provozovatele webu, a ten za jejich obsah neodpovídá.

phpFashion © 2004, 2012 David Grudlo webu

Pokud není uvedeno jinak, podléhá obsah těchto stránek licenci Creative Commons BY-NC-ND Creative Commons License BY-NC-ND

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.