以下の記事では、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');
ポイント
- キャッシュキー: 検索条件を基に一意のキャッシュキーを生成。
- キャッシュの保存と取得:
get_transient
でキャッシュを取得し、set_transient
でキャッシュを保存。 - キャッシュの有効期限:
DAY_IN_SECONDS
を利用して1日の期限を設定。
これにより、同じ検索条件でのAPIリクエストを1日1回に制限できます。