Google検索結果をWordPressに表示する キャッシュ対応

ブログ

以下の記事では、GoogleのカスタムSearch Engineを使った検索結果を表示するショートコードを作成しました。

APIレート制限

このままでも使うことはできますが、ページを読み込むごとに、APIにアクセスするので、
場合によっては、APIのレート制限に引っかかってしまいます。

そこで、今回は、APIレート制限に引っかからないように、更新は1日に1回になるように、キャッシュを活用するように改善したと思います。

WordPressのキャッシュ機能

WordPressには標準でキャッシュを扱う機能が備わっています。
transientsを使うことで、WordPressのデータベースに一時的なキャッシュデータを保存できます。

詳しくは以下の記事で紹介しています。

改善後のショートコード

改善したショートコード用のコードは以下になります。

function get_google_search_results($keyword, $site = '', $limit = 5, $date_restrict = '', $exact_terms = '', $exclude_terms = '', $title_filter = '') {
    $cache_key = 'google_search_' . md5(serialize(compact('keyword', 'site', 'limit', 'date_restrict', 'exact_terms', 'exclude_terms', 'title_filter')));
    $cached_results = get_transient($cache_key);

    if ($cached_results !== false) {
        // キャッシュが存在する場合、それを返す
        return $cached_results;
    }

    $api_key = GOOGLE_API_KEY;  // wp-config.phpに保存したAPIキー
    $cx = GOOGLE_CX;            // wp-config.phpに保存したカスタム検索エンジンID

    // Google Search APIのURL作成
    $query_params = [
        'q' => $keyword,
        'key' => $api_key,
        'cx' => $cx,
        'num' => $limit,
    ];

    if ($site) {
        $query_params['siteSearch'] = $site;
        $query_params['siteSearchFilter'] = 'i';
    }
    if ($date_restrict) {
        $query_params['sort'] = 'date:r:' . $date_restrict;
    }
    if ($exact_terms) {
        $query_params['exactTerms'] = $exact_terms;
    }
    if ($exclude_terms) {
        $query_params['excludeTerms'] = $exclude_terms;
    }

    $api_url = 'https://www.googleapis.com/customsearch/v1?' . http_build_query($query_params);

    $response = wp_remote_get($api_url);
    $results = [];

    if (!is_wp_error($response)) {
        $body = wp_remote_retrieve_body($response);
        $data = json_decode($body, true);
        if (isset($data['items'])) {
            $results = $data['items'];
        }
    }

    if ($title_filter) {
        $results = array_filter($results, function($item) use ($title_filter) {
            return stripos($item['title'], $title_filter) !== false;
        });
    }

    foreach ($results as &$item) {
        $thumbnail = '';

        if (isset($item['pagemap']['cse_image'][0]['src'])) {
            $thumbnail = $item['pagemap']['cse_image'][0]['src'];
        } elseif (isset($item['pagemap']['cse_thumbnail'][0]['src'])) {
            $thumbnail = $item['pagemap']['cse_thumbnail'][0]['src'];
        } elseif (isset($item['pagemap']['metatags'][0]['og:image'])) {
            $thumbnail = $item['pagemap']['metatags'][0]['og:image'];
        }

        $item['thumbnail'] = $thumbnail;
    }

    // キャッシュに保存(有効期限を1日に設定)
    set_transient($cache_key, $results, DAY_IN_SECONDS);

    return $results;
}

function google_search_shortcode($atts) {
    $atts = shortcode_atts([
        'keyword' => '',
        'site' => '',
        'limit' => 5,
        'date_restrict' => '',
        'exact_terms' => '',
        'exclude_terms' => '',
        'title_filter' => ''
    ], $atts);

    $results = get_google_search_results($atts['keyword'], $atts['site'], $atts['limit'], $atts['date_restrict'], $atts['exact_terms'], $atts['exclude_terms'], $atts['title_filter']);

    ob_start();
    ?>
    <div class="google-search-results">
        <h2>検索結果</h2>
        <?php if ($results): ?>
            <ul class="google-search-list">
                <?php foreach ($results as $item): ?>
                    <a href="<?php echo esc_url($item['link']); ?>" target="_blank" class="google-search-item">
                        <li>
                            <p class="google-search-title"><?php echo esc_html($item['title']); ?></p>
                            <div class="google-search-thumbnail-snippet">
                                <?php if (!empty($item['thumbnail'])): ?>
                                    <img class="google-search-thumbnail" src="<?php echo esc_url($item['thumbnail']); ?>" alt="Thumbnail">
                                <?php endif; ?>
                                <p class="google-search-snippet"><?php echo esc_html($item['snippet']); ?></p>
                            </div>
                        </li>
                    </a>
                <?php endforeach; ?>
            </ul>
        <?php else: ?>
            <p>検索結果が見つかりませんでした。</p>
        <?php endif; ?>
    </div>
    <?php
    return ob_get_clean();
}

add_shortcode('google_search', 'google_search_shortcode');

ポイント

  1. キャッシュキー: 検索条件を基に一意のキャッシュキーを生成。
  2. キャッシュの保存と取得: get_transientでキャッシュを取得し、set_transientでキャッシュを保存。
  3. キャッシュの有効期限: DAY_IN_SECONDSを利用して1日の期限を設定。

これにより、同じ検索条件でのAPIリクエストを1日1回に制限できます。

タイトルとURLをコピーしました