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.