让WordPress使用QQ头像

WordPress QQ Gravatar
  首先,最近不少用户使用QQ邮箱发评论,这自然就提供了一个很好的条件,为了利用这些QQ号,因此我将QQ邮箱的用户使用其QQ头像,感觉还是不错的。同时充分利用头像的缓存,虽然目前Gravatar还没有挂掉,估计速度也不咋的。
  首先谈谈这个头像的下载机制,QQ头像下载地址相对比较机密,

return "http://q1.qlogo.cn/g?b=qq&nk={$qq}&s=100&t=" . time();

,下载页相对容易。其次Gravatar的地址就更加明了,默认的就是这个。首先,谈谈怎么替换头像地址,代码如下,看不懂的请跳过。

function my_avatar($avatar){
    preg_match_all("/http:\\/\\/(.*)\\/avatar\\/([0-9a-zA-Z]+)(.*?)\'/", $avatar, $matches);
    $sid = $matches[2][0];
    return str_replace($matches[0][0], home_url() . "/avatar/{$sid}.png'", $avatar);
}
add_filter('get_avatar', 'my_avatar');

  网上关于这段代码还是挺多的,只是我这里的处理稍有不同,我将所有大小的图片进行了一个统一,使用我自定义目录avatar下面的sid.png文件,有一个问题是,这里如何知道我的QQ号呢,稍后继续说明。这一部只是完成了头像地址的替换,访问所有页面头像地址均会被替换,不得不说还是很赞的,同时不会泄露邮箱信息。
  下一个问题,如何获取对应的QQ号,怎么做?当然,需要用到我们的数据表来存储信息了。建立一个wp_avatar的表,相对很简单,两个字段,一个sid,一个email,用于对应的查询,SQL创建如下:

CREATE TABLE IF NOT EXISTS `wp_avatar` (
  `sid` CHAR(32) NOT NULL,
  `email` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`sid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

  然后要做的就是将邮箱信息存储到数据库中,这个再使用另一个钩子就行了,例如这里用到的,preprocess_comment,代码如下:

function add_comment_user_email($comment){
    $email = strtolower($comment['comment_author_email']);
    /**
     * @var wpdb $wpdb
     */

    global $wpdb;
    $sid = md5($email);
    $out = $wpdb->query("select `sid` from `".$wpdb->prefix."avatar` where `sid`='{$sid}';");
    if($out==0){
        $wpdb->insert($wpdb->prefix."avatar",['sid'=>$sid,'email'=>$email]);
    }
    return $comment;
}
add_action('preprocess_comment','add_comment_user_email');

  其作用只是将不存在的邮箱插入到数据库,并不复杂,这里并没有做头像的下载等操作,真正的问题再后面。

  首先,访问头像时访问的路径是/avatar/ababababbabbababababababababab.png之类的地址,并不是加什么参数,这里就需要用到伪静态了,这个强大的东西,非用不可,让它帮助我们完成强大功能的实现。不过先要实现的是如何将头像下载并存储。代码如下:

<?php
$sid = isset($_GET['id']) ? strtolower($_GET['id']) : "";
if(preg_match("/^[0-9a-z]{32}$/", $sid) === 1){
    $pdo = new PDO("mysql:host=127.0.0.1;dbname=db", "root", "123456");
    $stmt = $pdo->prepare("select * from `wp_avatar` where `sid`=:sid LIMIT 0,1;");
    $stmt->execute([':sid' => $sid]);
    $d = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $stmt->closeCursor();
    unset($pdo);
    if(isset($d[0]['email'])){
        $d = $d[0]['email'];
        $ss = NULL;
        if(preg_match("/^[1-9]{1}[0-9]{4,11}@qq\\.com^/", $d) == 0){
            $index = strpos($d, "@");
            $u = substr($d, 0, $index);
            $ss = file_get_contents(get_qq_avatar_src($u));
            if(in_array(strlen($ss), [
                3707,//这两个是默认头像的大小,如果默认大小就不需要吧,企鹅可不好看。
                7097,
            ])
            ){
                $ss = NULL;
            }
        }
        if(empty($ss)){
            $ss = file_get_contents(get_gravatar($sid));
        }
        file_put_contents(__DIR__."/avatar/".$sid . ".png", $ss);
        header("location: /avatar/{$sid}.png");
        return;
    }
}

function get_qq_avatar_src($qq){
    return "http://q1.qlogo.cn/g?b=qq&nk={$qq}&s=100&t=" . time();
}

function get_gravatar($sid){
    $host = sprintf("http://%d.gravatar.com", (hexdec($sid[0]) % 2));
    return "{$host}/avatar/{$sid}?s=100";
}

header("location: /avatar/default.jpg");

  这是下载的代码,访问方式如avatar.php?id=ababababbabababbaba,但是并不是特别友好,但是确实是在下载,并且当头像不存在时直接跳转到default.jpg的头像位置,所以还需要自定义默认头像,也是不错的选择。同时将文件写入avatar文件夹,也就意味着文件夹必须可写。注意创建。回到之前的需要,当头像不存在时,自动跳转到avatar.php?id=……这个地址,伪静态开始实现。下面的nginx代码,没有apache的,应该会更简单,看看nginx的应该能大致弄清。

location ~ /avatar/{
    if (!-f $request_filename){
        rewrite ^/avatar/(.*)\.png$  /avatar.php?id=$1 last;
    }
}

  最后的访问效果你们可以自己现在试试,试试你自己用QQ邮箱,必须是QQ号,否则会出错。我感觉还是挺好的,之前看到网上有人有这样的需求,不知道别人如何解决的呢,期待有更好的办法吧,当然不能是改源代码的方式,那就没意义了。

  补充一点,关于批量导出已有的邮箱列表,方法如下,执行out.php即可,代码如下,将导出问SQL语句直接执行就OK,非常之方便。

$pdo = new PDO("mysql:host=127.0.0.1;dbname=wp", "root", "123456");
$stmt = $pdo->query("select `comment_author_email` from `wp_comments` where 1 group by `comment_author_email`");
echo "insert into `avatar` (`sid`,`email`)values \n";
$f = 0;
while(($d = $stmt->fetch(PDO::FETCH_ASSOC))){
    if(!empty($d['comment_author_email'])){
        if($f != 0){
            echo ",\n";
        } else{
            $f = 1;
        }
        $d = strtolower($d['comment_author_email']);
        echo "(", $pdo->quote(md5($d)), ",", $pdo->quote($d) . ")";
    }
}
echo ";";

你可以访问Github查看新代码:https://github.com/loveyu/wp-cache-avatar

20条评论在“让WordPress使用QQ头像”

  1. 我记得以前用过缓存QQ空间头像的插件,评论时填写的邮箱地址必须使用“数字@qq.com”这样的邮箱才能显示出头像,好像是这样,呵呵…

写下你最简单的想法