首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

WordPress Gravatar 頭像本地緩存與優化完整方案

     編輯:PHP 相關知識

WordPress Gravatar 頭像本地緩存與優化完整方案

Gravatar 官方伺服器位於國外,受 GFW 影響國內訪問極慢,嚴重拖慢頁面載入。本文提供三層遞進的解決方案:基礎緩存、Email 預檢、完整優化版,徹底解決頭像載入慢問題。

方案一:基礎本地緩存(14 天過期)

function my_avatar($avatar) {
  $tmp = strpos($avatar, 'http');
  $g = substr($avatar, $tmp, strpos($avatar, "'", $tmp) - $tmp);
  $tmp = strpos($g, 'avatar/') + 7;
  $f = substr($g, $tmp, strpos($g, "?", $tmp) - $tmp);
  $w = get_bloginfo('wpurl');
  $e = ABSPATH . 'avatar/' . $f . '.jpg';
  $t = 1209600; // 14 天
  
  if (!is_file($e) || (time() - filemtime($e)) > $t) {
    copy(htmlspecialchars_decode($g), $e);
  } else {
    $avatar = strtr($avatar, array($g => $w . '/avatar/' . $f . '.jpg'));
  }
  
  // 檔案過小視為無效,替換為預設頭像
  if (filesize($e) < 500) copy($w . '/avatar/default.jpg', $e);
  
  return $avatar;
}
add_filter('get_avatar', 'my_avatar');

部署步驟

  1. WordPress 根目錄建立 avatar/ 資料夾,權限 0755(或 0777)
  2. 準備 32×32 預設頭像命名 default.jpg 放入該資料夾
  3. 將上述代碼加入主題 functions.php

方案二:Email 預檢是否有 Gravatar(避免無效請求)

function validate_gravatar($email) {
  $hash = md5(strtolower(trim($email)));
  $uri = 'https://www.gravatar.com/avatar/' . $hash . '?d=404';
  $headers = @get_headers($uri);
  return (preg_match("|200|", $headers[0])) ? true : false;
}

用法:if (validate_gravatar($email)) echo get_avatar($email); else echo '本地預設頭像';

方案三:完整優化版(30 天緩存、避免重複預設頭像、支援多尺寸)

function my_avatar($email, $size = '32', $default = '', $alt = '') {
  $f = md5(strtolower($email));
  
  // 路徑配置:緩存到主題目錄下的 avatar/ 資料夾
  $a = get_bloginfo('template_url') . '/avatar/' . $f . $size . '.png'; // URL
  $e = get_template_directory() . '/avatar/' . $f . $size . '.png';     // 實體路徑
  $d = get_template_directory() . '/avatar/' . $f . '-d.png';          // 無頭像標記檔
  
  if ($default == '') $default = get_bloginfo('wpurl') . '/avatar/default.jpg';
  $t = 2592000; // 30 天緩存
  
  // 本地緩存不存在或過期
  if (!is_file($e) || (time() - filemtime($e)) > $t) {
    // 無頭像標記不存在或過期 → 驗證遠端
    if (!is_file($d) || (time() - filemtime($d)) > $t) {
      $uri = 'https://www.gravatar.com/avatar/' . $f . '?d=404';
      $headers = @get_headers($uri);
      
      if (!preg_match("|200|", $headers[0])) {
        // 無頭像:建立空標記檔,避免重複請求
        $handle = fopen($d, 'w'); fclose($handle);
        $a = $default;
      } else {
        // 有頭像:下載並緩存
        $r = get_option('avatar_rating');
        $g = 'https://www.gravatar.com/avatar/' . $f . '?s=' . $size . '&r=' . $r;
        copy($g, $e);
      }
    } else {
      // 有無頭像標記 → 直接用預設
      $a = $default;
    }
  }
  
  $avatar = "<img alt='{$alt}' src='{$a}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}' />";
  return apply_filters('my_avatar', $avatar, $email, $size, $default, $alt);
}

使用方式替換

// 原來
get_avatar($comment, 48);

// 改為
my_avatar($comment->comment_author_email, 48);

// 或
my_avatar($comment, 48); // 需修改函數第一參數判斷型別

效能對比與優化要點

方案遠端請求預設頭像重複緩存策略適用場景
基礎版每新用戶一次會產生多個 default.jpg14 天簡單部落格
優化版首次驗證+下載空標記檔機制完全避免30 天高流量站點

進階建議

  • HTTPS 支援:將 https://www.gravatar.com 改為 https://secure.gravatar.com 或 https://cn.gravatar.com(國內鏡像)
  • CDN 加速:將 avatar/ 目錄掛載到 CDN 或對象儲存(OSS/S3)
  • WebP 格式:下載後轉 WebP 縮減 30% 體積 imagewebp()
  • 預熱機制:定時任務掃描評論表預先下載熱門用戶頭像

核心原則:以空間換時間、以標記檔換請求。優化版通過 -d.png 標記檔徹底解決「無頭像用戶重複請求 404」與「預設頭像產生大量重複檔案」兩大痛點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved