Schau dir auch die anderen Artikel an: Zum Leitartikel
Vor einigen Tagen schrieb ich bereits über eine Möglichkeit, die Gravatar-Icons lokal zwischen zu speichern. Leider wurde dabei bei jedem Aufruf eines Bildes immer einen php-call gemacht, was mir bei manchen Beiträgen das Blog in die Knie zwingen würde und dem eigentlich gewünschten Effekt (Beschleunigung) entgegenstehen würde. Daher habe ich mir mal die Funktionen meines Webservers nginx angesehen und dabei festgestellt, dass dieser die folgende Prüfung erlaubt:
- Ist das Bild vorhanden?
- Wenn ja: Direkte Auslieferung
- Wenn nein: Aufruf einer PHP-Datei zum Download des Bildes
Die Umsetzung war dann einfach:
Das ist die Konfigurationsdatei für den vHost in nginx:
-
server {
-
listen 80;
-
server_name img.yourdomain.tld;
-
error_log /path/to/your/logs/error/img.yourdomain.tld.log warn;
-
root /path/to/your/document/root/;
-
-
location ~ \.php$ {
-
fastcgi_pass 127.0.0.1:1234;
-
include /etc/nginx/fastcgi_params;
-
}
-
-
location / {
-
index cdn.php;
-
# if the requested file exists, return it immediately
-
if (-f $request_filename) {
-
break;
-
}
-
-
# all other requests go to CDN-PHP-File
-
if (!-e $request_filename) {
-
rewrite ^(.+)$ /cdn.php last;
-
}
-
}
-
}
Nun speichert man in /path/to/your/document/root/ die Datei cdn.php mit folgendem Inhalt:
-
<?php
-
// Script by Uli Wolf - http://wolf-u.li
-
-
// Modify the settings below according to your needs:
-
// Size of the gravatar-images:
-
$gimagesize = 32;
-
-
// If the mailadress was not found, you can get various images:
-
// - identicon
-
// - monsterid
-
// - wavatar
-
$mailnotfound = "identicon";
-
-
$removefromurl = array("/g/","/",".png",".jpg",".gif");
-
$gravatar_hash = str_replace(strtolower($removefromurl),"",$_SERVER["REQUEST_URI"]);
-
$gravatar_hash = preg_replace("/[^a-z0-9\s]/", "", $gravatar_hash);
-
if(strlen($gravatar_hash)!=32) {exit;}
-
$grav_img = "http://www.gravatar.com/avatar/" . $gravatar_hash . "?s=" . $gimagesize . "&d=" . $mailnotfound . "&r=G";
-
if(extension_loaded('curl')) {
-
$gch = curl_init();
-
$gcurl_options = array(
-
CURLOPT_URL => $grav_img,
-
CURLOPT_HEADER => false,
-
CURLOPT_RETURNTRANSFER => true,
-
CURLOPT_TIMEOUT => 20,
-
CURLOPT_BINARYTRANSFER => true,
-
CURLOPT_MAXREDIRS => 2
-
);
-
curl_setopt_array($gch, $gcurl_options);
-
-
$gdata = curl_exec($gch);
-
curl_close ($gch);
-
unset($gch);
-
} else {
-
ob_start();
-
$gfilehandle_url = fopen($grav_img, "rb");
-
fpassthru($gfilehandle_url);
-
fclose($gfilehandle_url);
-
$gdata = ob_get_contents();
-
ob_end_clean();
-
unset($gfilehandle_url);
-
}
-
$gfilehandle_img = fopen("g/" . $gravatar_hash . ".png", "wb+");
-
fwrite($gfilehandle_img, $gdata);
-
fclose($gfilehandle_img);
-
unset($gfilehandle_img);
-
-
header('content-type: image/png');
-
echo $gdata;
-
?>
Was macht diese Datei?
Oben kann man zunächst einstellen, wie groß die Bilder sein sollen und welches Bild angezeigt werden soll, wenn nix hinterlegt ist. Anschließend wird eine Prüfung der URL durchgeführt, die einige mögliche Angriffsvektoren ausfiltern soll. Dabei bleiben dann nur Strings mit 32 Zeichen in Groß- und Kleinbuchstaben übrig, andernfalls wird das Script beendet. Im Anschluss wird dann das Bild geholt (per curl, wenn möglich), gespeichert und ausgegeben. Das verzeichnis /path/to/your/document/root/g/ sollte hierzu vorhanden sein.
Warum der Unterordner /g/? Ich wollte mir damit offen halten, verschiedene Bildertypen zu cachen. Das habe ich gelöst, indem ich meinen Bilderhashes ein "/g/" vorstelle, welches diese als Gravatar-Bilder markiert. Fällt mir also irgendwann mal ein, dass ich beispielsweise gerne noch Pavatar (wie auch immer geartet) cachen möchte, dann kann ich dies hier einbauen.
Meine Url sieht also am Ende so aus:
http://img.yourdomain.tld/g/a9ec4695d424a6dcb6f896afb0ee22bc.png
und wird bei ersten Aufruf gecached mittels php und anschließend in den weiteren Aufrufen immer statisch durch den Webserver ausgegeben. Möchte man nun regelmäßig die Bilder aktualisieren, empfiehlt es sich, das hier bereits vorgestellte Script in regelmäßigen Abständen laufen zu lassen.
Für den Einbau in Wordpress ist das ganze auch recht einfach. Man öffnet die comments.php und sucht darin den Aufruf:
-
<?php echo get_avatar( $comment, 32); ?>
Diesen ersetzt man dann durch:
-
<?php echo "<img src='http://img.yourdomain.tld/g/" . md5(strtolower(get_comment_author_email())) . ".png' height='32' width='32'>"; ?>
Wobei die Domain und die Größe natürlich austauschbar sind.
Zu guter letzt noch ein Hinweis für Apache-Nutzer: Das PHP-Script lässt sich natürlich auch mit diesem Webserver nutzen.











Weißt du, ob es eine entsprechende Funktion für Apache gibt?
Sicher, musst dich mal bei den mod_rewrite-Geschichten umschauen