网站评论者头像接入QQ头像并缓存本地

需求是:优先显示 Gravatar 头像,如果不存在或使用了没注册 Gravatar 的邮箱则显示其他关联的头像,其中如果是数字QQ邮箱,则尝试显示该数字QQ号的头像,头像都缓存到服务器硬盘上。

QQ头像API

1、示例:http://q1.qlogo.cn/g?b=qq&nk=1351397556&s=100
参数说明:

  • b:qq(固定参数)
  • nk:你要获取头像的QQ
  • s:头像尺寸(详情见下文)

头像尺寸:

  • s=1 尺寸:40 × 40
  • s=2 尺寸:40 × 40
  • s=3 尺寸:100 × 100
  • s=4 尺寸:140 × 140
  • s=5 尺寸:640 × 640
  • s=40 尺寸:40 × 40
  • s=100 尺寸:100 × 100
  • s=140 尺寸:* × *
  • s=640 尺寸:* × *

如果该尺寸不存在可能会使用默认白底企鹅图片代替,使用 100 较稳。
同时 q.qlogo.cn、q2.qlogo.cn、q3.qlogo.cn、q4.qlogo.cn 等都可用。
2、
https://q2.qlogo.cn/headimg_dl?dst_uin=1351397556&spec=100
3、
http://ptlogin2.qq.com/getface?imgtype=1&uin=1351397556
https://ssl.ptlogin2.qq.com/getface?imgtype=4&uin=1351397556
其中 imgtype= 的值范围 1~4 可以获得不同尺寸的头像。
返回:

pt.setHeader({
  "1351397556": "https://thirdqq.qlogo.cn/g?b=sdk&k=jEHFNzdtIcxib1T14ibicxehA&s=100&t=1554108907"
})

可以直接打开链接即是头像,也可以获取链接中的 k 值,代入
http://q1.qlogo.cn/g?b=qq&k=jEHFNzdtIcxib1T14ibicxehA&s=4
来获取不同尺寸的头像。

关键代码

直接输出以上QQ API的地址到访客浏览器端是效率最高的,但是会有直接暴露评论者隐私的风险,使用 K 值代替QQ号也需要额外的发起一次网络请求,对比直接缓存到服务器本地没有特别大的优势。

要不是这死二次元下面代码里弄了些奇奇怪怪的东西,就直接拿来用了。

<?php
//首先要创建一个缓存文件夹ABSPATH . 'avatar/'  网站根目录?
//https://www.box***.com/436.html 还以为是这厮创的呢XXX
//出处https://www.raineggplant.com/replace-gravatar-by-qq-avatar.html
function my_get_avatar($avatar, $id_or_email, $size) {    
    // Get the author's email.
    $email = '';
    if ( is_numeric($id_or_email) ) {
        $id = (int) $id_or_email;
        $user = get_userdata($id);
        if ( $user )
            $email = $user->user_email;
    } elseif ( is_object($id_or_email) ) {
        if ( !empty($id_or_email->user_id) ) {
            $id = (int) $id_or_email->user_id;
            $user = get_userdata($id);
            if ( $user)
                $email = $user->user_email;
        } elseif ( !empty($id_or_email->comment_author_email) ) {
            $email = $id_or_email->comment_author_email;
        }
    } else {
        $email = $id_or_email;
    }
    
    // Get the url of avatar
    $pattern = '/(?=http)[-\w:\/\.?&#;=]+/';
    $url_count = preg_match_all($pattern, $avatar, $original_avatar_url);
    $avatar_size = array();
    $avatar_url = array();
    $pattern = '/(?<=s=)\d+/';
    for ( $i = 0; $i < $url_count; ++$i) {        
        preg_match($pattern, $original_avatar_url[0][$i], $size_array);    
        $avatar_url[$i] = $original_avatar_url[0][$i];
        $avatar_size[$i] = $size_array[0];
    }
    
    // Check if the author has a gravatar.
    $hashkey = md5(strtolower(trim($email)));
    $test_url = 'http://www.gravatar.com/avatar/' . $hashkey . '?d=404';
    $data = wp_cache_get($hashkey);
    if ( false === $data ) {
        $response = wp_remote_head($test_url);
        if( is_wp_error($response) ) {
            $data = 'not200';
        } else {
            $data = $response['response']['code'];
        }
        wp_cache_set($hashkey, $data, $group = '', $expire = 60*5);
    }
    
    if ( $data != '200' ) {        
        // The author doesn't have a gravatar.
        if ( stripos($email,"@qq.com") ) {
            // If he uses QQ mail, let WordPress use his QQ avatar instead.
            // Set the size of QQ avatar.
            for ( $i = 0; $i < $url_count; ++$i) {                    
                if ( $avatar_size[$i] <= 100 ) $qq_avatar_size = 100;
                elseif ( $size <= 140 ) $qq_avatar_size = 140;
                elseif ( $size <= 240 ) $qq_avatar_size = 240;
                else $qq_avatar_size = 640;
                // q1.qlogo.cn, q3.qlogo.cn, q4.qlogo.cn also work.
                $avatar_url[$i] = 'http://q2.qlogo.cn/g?b=qq&nk=' . $email . '&s=' . $qq_avatar_size;
            }
        }
    }
    // Unfortunately I don't know what encrypt method the QQ avatar interface accepts.
    // So to protect the author's privacy, I have to cache the avatars.
    $wp_url = get_bloginfo('wpurl');
    // Caching.
    for ( $i = 0; $i < $url_count; ++$i) {
        $file_path = ABSPATH . 'avatar/' . $hashkey . '-' . $avatar_size[$i] . '.jpg';
        // 1209600s = 14d, the avatars will be cached for 2 weeks. You can change the period.
        $lifetime = 1209600; 
        if ( !is_file($file_path) || (time() - filemtime($file_path) ) > $lifetime) { 
            // If the file doesn't exist or it has been out of date, then update it.
            // It's necessary to use "-N --no-use-server-timestamps".
            exec("wget -N --no-use-server-timestamps -O '" . $file_path . "' '" . $avatar_url[$i] . "'  > /dev/null &");                        
        }
        else $avatar = str_replace($original_avatar_url[0][$i], $wp_url . '/avatar/' . $hashkey . '-' . $avatar_size[$i] . '.jpg', $avatar);
        if ( filesize($file_path) < 500 ) copy($wp_url . '/avatar/default.jpg', $file_path);
    }
    return $avatar;    
}
add_filter( 'get_avatar', 'my_get_avatar', 10, 3);
?>
  • 要求在网站根目录建立缓存文件夹,这是很不喜欢的事情,跟主题有关的东西放在主题目录里就好了,越界了。
  • wp_cache_get()、wp_cache_set() 这用的咱们也看不明白,也没地方问。
  • exec()在关键地方执行系统 shell 命令,很多系统都没默认安装的“wget”,虽然它很常用,也不利于后续维护,完全不能接受的骚操作。

思路较清晰,实现过程比较合我胃口,候选方案。

以下是现在使用的方法。

《网站评论者头像接入QQ头像并缓存本地》
使用 Copy() 来下载网络图片,效率低下,之前删除所有缓存图片后打开头像多的页面直接不停不停加载然后就502,建议 curl 库来完成。

/**@通过curl方式获取制定的图片到本地
  *@ 完整的图片地址
  *@ 要存储的文件名
**/

function mydownload($url, $filename)
{
    $referer='https://www.guihet.com/';
    $ch = curl_init ();  
    curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, 'GET' );  
    curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false );  
    curl_setopt ( $ch, CURLOPT_URL, $url );  
    curl_setopt ($ch,CURLOPT_REFERER,$referer); 
    ob_start ();  
    curl_exec ( $ch );  
    $return_content = ob_get_contents ();  
    ob_end_clean ();         
    $return_code = curl_getinfo ( $ch, CURLINFO_HTTP_CODE );  
    $fp= @fopen($filename,"a"); 
    fwrite($fp,$return_content);  
    return true; 
}

还有很多纰漏,先运行起来,后续慢慢解决。
本次功能部分代码基于之前本站的方案:网站服务器缓存Gravatar头像

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

  1. 若非 说道:

    优秀,虽然看不懂,但是最后一句我明白,坐等完美版。 ?

    1. 黑鸟 说道:

      这种方式必须配合服务器本地缓存头像,自己用的话三板斧随便搞,要拿出去分享还欠些火候。

  2. 黑鸟 说道:

    这样组合起来写 $userEmail = get_user_by( 'email', (int) $id_or_email); 好像取不到想要的结果,非得把 id 分来来写多写一行?不会 PHP 搞不明白了。

  3. 龙笑天 说道:

    我主题的头像规则是:注册用户头像 > Gravatar > QQ > 名字首字。 :019:

    1. 黑鸟 说道:

      大佬牛批,注册用户不用活跃我这,也不会活跃,先不管了。

      1. 龙笑天 说道:

        你这咋没评论回复邮件提醒... :025:

        1. 黑鸟 说道:

          不知道哪一天开始,不知是邮箱问题还是服务器问题还是动了主题某个地方的问题,反正就是不能用了,也不想追究了,这东西兴趣不大,随缘交流。

        2. 黑鸟 说道:

          去检查重新配置了下,估计可以用了,原来只是扣扣邮箱只能允许授权码登录了啊,获取登录授权码还得扣扣绑定手机二代密保真烦。 :007:

          1. 龙笑天 说道:

            很6 邮件样式很赞 :017:
            PS:搞个域名邮箱撒~

        3. 黑鸟 说道:

          比起来还是大佬的邮箱样式高级多了。
          在扣扣域名邮箱没有独立出去时候用过一段时间,现在关联到微信那辣鸡东西去,太复杂了不方便配置现在,就这样先用着 ..

  4. 黑鸟 说道:

    实际上现在只要把头像接入 cravatar.cn 这李鬼家就可以自动实现QQ头像的显示 :022:

    1. 黑鸟 说道:

      不行,好像又漏掉几种情况,得修 :037: