xjpvictor's Blog
小老鼠,上灯台,两只耳朵竖起来

wordpress之gravatar缓存


各种折腾·phpprojectwordpress

本文发表于超过180天以前,部分内容可能已经失效

之所以要缓存gravatar头像,是为了加快速度,省略对gravatar.com的https请求,而之所以用https,是为了避免某反动势力的窥探。嗯,你们这些与全社会作对的,是历史的倒退,总有一天会颠覆在人民的汪洋大海中,毛主席的红色小卫兵们,冲啊!!

扯远了,回来。wordpress有些插件也是可以缓存gravatar头像的,但是因为科技的进步,这些久不更新的插件虽然勉强能用,但是总有些问题,甚至可能导致头像不显示,所以只好人肉写代码了。

其实是很简单的。wordpress显示头像是使用了 get_avatar 函数,这个函数在 /wp-include/pluggable.php 文件中,而查看源代码发现这个函数是返回了这么一个string

<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}' />

所以只需要在主题文件的functions.php中添加一个filter,然后把src中的图片地址替换掉,改成自己服务器上图片的地址。

function my_get_avatar($text) {
  preg_match('/https:\/\/secure.gravatar.com\/avatar\/([a-z0-9]+)\?s=(\d+)(?:\S*)&r=(\w*)/',$text,$match);
  $ourl = $match[0];
  $email_hash = $match[1];
  $size = $match[2];
  $rate = $match[3];
  $ch = curl_init("http://en.gravatar.com/{$email_hash}.php");
  curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
  curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,10);
  curl_exec($ch);
  $info = curl_getinfo($ch,CURLINFO_HTTP_CODE);
  curl_close($ch);
  if ( $info === 404 ) {
	  $url = '/wp-content/themes/gravatar/default_'.$size;
  } else {
	  if ( empty($rate) ) {
	  	$rate = "G";
	  }
	  $file = $_SERVER["DOCUMENT_ROOT"].'/wp-content/themes/gravatar/'.$email_hash.'_'.$size.'_'.$rate;
	  if ( !file_exists($file) ) {
	  	$img = file_get_contents("https://secure.gravatar.com/avatar/{$email_hash}?s={$size}&d=mm");
	  	file_put_contents($file,$img);
	  }
	  $url = '/wp-content/themes/gravatar/'.$email_hash.'_'.$size.'_'.$rate;
  }
  return preg_replace('/src=\'\S+\'/',"src='{$url}'",$text);
}
add_filter('get_avatar','my_get_avatar');

这个代码就是把get_avatar返回的string再传递给my_get_avatar,这时候就可以从这个string中找出头像图片的地址,从而提取出这个地址中包含的用户的email地址的md5 hash值和头像的大小以及分级。

然后用这个email的md5 hash值查看这个用户是否有gravatar头像,如果没有就直接使用默认的头像。否则就查看服务器上是不是已经有了缓存的图片,如果没有,那就去gravatar.com下载,如果有了就直接使用缓存的图片。最后用服务器上的图片的地址替换掉get_avatar函数输出的地址,再把这一整串替换过图片地址的<img xxx />作为结果返回。这时候wordpress再调用get_avatar函数时就会执行这个filter,图片地址就会自动替换了。

用的时候先建立图片储存的目录,/wp-content/themes/gravatar/ ,然后在里面放上默认头像,格式是 default_{$size} 。比如评论中的头像大小是32,那就放个 default_32 作为默认头像。因为默认头像并不会自动下载,所以要事先把需要用到的各个大小的默认头像都下载一份。然后如果某个有gravatar头像的新读者留言了,因为评论中的头像大小是32,于是就会下载相应的头像图片,并以格式 {$email_hash}_{$size}_{$rate} 存在服务器中,以后这个用户的头像就都会使用这个服务器中的副本了。

有个缺点是没有考虑到用户更换gravatar头像,所以可以做个cron任务,隔一段时间把 /wp-content/themes/gravatar/ 中除了默认头像的所有文件删除。另一个缺点是如果用户的gravatar帐号绑定了多个email,而用户留言用的不是主email,那么就无法显示他的头像了。因为在判断用户是否有gravatar头像的时候,只要不是主email都会返回的是没有头像,这其实是gravatar提供的用来判断用户是否存在的api的限制。

Update 2013-01-31:
做了个插件版:传送门

本文 "wordpress之gravatar缓存" 由 K. Huang 首先发表于 xjpvictor's Blog 并以 CC BY-NC 4.0 许可证发布 © 2012
转载注明引用来源 https://blog.xjpvictor.info/2012/05/gravatar-cache/

赞助我

一条评论

  1. 谢谢你 试试看这个代码效率如何

    回复

评论

你的邮箱地址不会被公开。必填项以 * 标出

无意义或不相关评论将被删除

取消 上传图片 或拖拽上传

* Some files will not be uploaded. Only png, gif, jpg are allowed and maximum 10 images, each file less than 10M.

你可以添加 10 个 png/gif/jpg 图片 (每个文件小于 10M)

允许使用以下html标签:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

你可以上传文件,粘贴代码或长文至 Drop.it.r

更多相似文章