gravatar老早就被墙了,以前很好用的随机头像服务随之完蛋,网上搜罗一番,找到了一些解决的办法:

  1. 使用gravatar的https服务,试过一段时间,发现不稳定,有时候会连接不上,而且可能很快继续被墙。
  2. 使用duoshuo的镜像,参数和结果跟gravatar一样,这个还算靠谱,但是有很少的情况下也会刷不出来,至于原因我已经懒得研究了,因为我决定自己建立随即头像服务。
  3. 还有一种比较复杂的方法,大家网上搜索gravatar七牛镜像,看起来稳定性还不错,不过既然要创建一个服务自己用,我更喜欢创建在自己的服务器上 :)

那么我来简单教大家建立自己的类似gravatar的随机头像服务,不过这种方法是需要一点php基础的。

源码托管在github:https://github.com/sevensth/DWRA.git

首先下载wp_identicon插件,解包拿出wp_identicon.php文件,额,当然这里你直接把这个插件装上用也是可以的,不过我的博客前端已经脱离wordpress,所以直接装上去除了能提醒我更新它以外,没有什么用。

注意wp_identicon是依赖php的GD扩展的,先确认自己是否支持,如果不支持,要先安装GD,方法就自行百度之吧。

首先,我们得检查一下wp_identicon的代码授权条例,但是我在网站和下载包中找了好久都没有找到,不过不用担心,最差预期是GPL授权,只要公开自己的代码就好了,何况我们也不是商业目的。

接下来我们要把wp_identicon的核心算法函数和类剥离出来,wp_identicon最重要的两个类是:

class identicon
class identicon_mersenne_twister

接下来找到文件头部的两个define,这是两个路径,一个用来拼接出图片网址路径,一个用来拼接图片的本地路径:

define('WP_IDENTICON_DIR',  str_replace('\\','/',preg_replace('@.*([\\\\/]wp-content[\\\\/].*)@','\1',dirname(__FILE__)).'/identicon/'));
define('WP_IDENTICON_DIR_INTERNAL', dirname(__FILE__).'/identicon/');

然后其他部分统统可以删除了:

define('WP_IDENTICON_DIR',  str_replace('\\','/',preg_replace('@.*([\\\\/]wp-content[\\\\/].*)@','\1',dirname(__FILE__)).'/identicon/'));
define('WP_IDENTICON_DIR_INTERNAL', dirname(__FILE__).'/identicon/');

class identicon {
    //注意class identicon里面的function identicon_display_parts这个函数也是没什么鸟用的,可以删除
}

//这个函数用来生成默认的配置,可以留着
function identicon_get_options(){
	$identicon_array=get_option('identicon');
	if (!isset($identicon_array['size'])|!isset($identicon_array['backb'])){
		//Set Default Values Here
		$default_array=array('size'=>35,'backr'=>array(255,255),'backg'=>array(255,255),'backb'=>array(255,255), 'forer'=>array(1,255),'foreg'=>array(1,255),'foreb'=>array(1,255),'squares'=>4,'autoadd'=>1,'gravatar'=>0,'grey'=>0);
		add_option('identicon',$default_array,'Options used by Identicon',false);
		$identicon_array=$default_array;
	}
	return($identicon_array);
}

class identicon_mersenne_twister{
}

接下来就是要去除一些wordpress提供的工具方法:

//这些方法都是wordpress提供的存取设置的方法,可以直接改掉
get_option
add_option

这些方法都是wordpress提供的存取设置的方法,可以直接改掉,替换成写死的常量,或者想办法去除掉即可,比如:

function identicon_get_options(){
	$identicon_array=get_option('identicon');
	if (!isset($identicon_array['size'])|!isset($identicon_array['backb'])){
		//Set Default Values Here
		$default_array=array('size'=>35,'backr'=>array(255,255),'backg'=>array(255,255),'backb'=>array(255,255), 'forer'=>array(1,255),'foreg'=>array(1,255),'foreb'=>array(1,255),'squares'=>4,'autoadd'=>1,'gravatar'=>0,'grey'=>0);
		add_option('identicon',$default_array,'Options used by Identicon',false);
		$identicon_array=$default_array;
	}
	return($identicon_array);
}
//直接改为
function identicon_get_options(){
	$default_array=array('size'=>35,'backr'=>array(255,255),'backg'=>array(255,255),'backb'=>array(255,255), 'forer'=>array(1,255),'foreg'=>array(1,255),'foreb'=>array(1,255),'squares'=>4,'autoadd'=>1,'gravatar'=>0,'grey'=>0);
	return($identicon_array);
}
//了事,:)

接下来我们要修正wp_identicon的两个路径宏:

define('WP_IDENTICON_DIR',  str_replace('\\','/',preg_replace('@.*([\\\\/]wp-content[\\\\/].*)@','\1',dirname(__FILE__)).'/identicon/'));
define('WP_IDENTICON_DIR_INTERNAL', dirname(__FILE__).'/identicon/');
//前一个是用来获取网址的子目录,后一个是用来获取cache图片的路径
//假如我们的随即头像服务根网址是http://xxx.com/dw/gravatar/,那么就这么写
define('WP_IDENTICON_DIR',  '/dw/gravatar/'));
//下面的基本不用改,意味着和wp_identicon.php相同目录下,还有一个叫identicon的目录,用来缓存图片
define('WP_IDENTICON_DIR_INTERNAL', dirname(__FILE__).'/identicon/');

注意,WP_IDENTICON_DIR_INTERNAL所指的目录是cache目录,一定要保证自己的php运行权限能对这个目录进行读和写,否则cache没法生成

ok,那么基础模块大功告成了,只要我们按照正确的姿势调用接口:

include 'wp_identicon.php';
    $idc = new identicon();
    //function identicon_build($seed='',$altImgText='',$img=true,$outsize='',$write=true,$random=true,$displaysize='',$gravataron=true)
    $avatar = $idc->identicon_build($seed, '', false, $size, true, true, $size, $gravatar);

这些参数的意义只要自己查查代码就可以明白了,这里简单说明一下:

$seed指的是输入的字符串,比较邮件地址,昵称等,函数会帮我们hash,所以不用hash过再传入。

$img为真时,返回的字符串不再是图片的网址,而是拼接好的img标签,当然如果为false时,altImgText也没有意义了。

outsize指的是生成图片的宽(正方形),而displaysize会在生成img标签时发挥作用,使得拉伸图片成为可能(其实这个选项真是没有什么卵用,我们只要定义一下css样式就行了)。

random一定要传入true,否则图片就不会随即了(我对传入false会发生什么毫无兴趣,所以我也没打算研究这个参数)。

注意最后一个参数不要传true,否则会自动进行gravatar的中转(被墙了),那毫无意义。

那么接下来要部署的就是服务器了,你可以集成在博客代码里面,也可以作为单独的服务,像gravatar那样,直接返回图片内容,比如我的:

https://function.dreamingwish.com/gravatar/c78fccb17b567e263d0bd863e776d77a?s=80&d=identicon&rating=pg&auth=7830559911c151d8b45ad606ec2d40b25b453d32aa25ebc8d4ddc53959497257&ak=e15b48f0

或者

https://function.dreamingwish.com/gravatar/1ab30d69e6fc35fcf7d34905c15a7aa8?s=80&d=identicon&rating=pg&auth=7dd0c31be044cfa0294d77254cccba031c28a4f154cb28e3a9e387cb523852ec&ak=e15b48f0

不过你看到,我的头像服务有两点不同:

  1. 支持固定解析的图片
  2. 有auth和ak参数,这是用来鉴权的,防止别人偷偷调用我们的服务,毕竟不能为别人做嫁衣(当然,你可以简单的为服务器配置图片防盗链,不过据我经验,图片防盗链会让自己用起来都不舒心)。

好了,那么下一节,我来为大家讲述如何支持上述两个特性。

评论模块尚未加载