目指せ軽量化!WordPressのTransient APIでDBキャッシュを生成、クリアする方法

php WordPressのカスタマイズ

以前、WordPressを高速化させる方法の一つとしてキャッシュ生成ができる wp_cache関数 を紹介しました。
>> 重いクエリをなんとかしたい!WordPressでキャッシュを生成して高速化させる方法
wp_cache関数は1アクセス中にのみ保持されるキャッシュを生成します。ページをまたいでキャッシュを保持するには特別なプラグインが必要です。このプラグインを使用しない状態でキャッシュを保持したい場合は、代わりに Transients API を利用することでDBキャッシュが利用できます。

今回は Transients API を使ったDBキャッシュの生成方法を紹介します。

Transients API とは

WordPressでは、渡されたデータに名前をつけて有効期限と共にDBに保存する機能が実装されています。保存したデータを Transient と呼び、この Transient を管理するのが Transient API です。

wp_cacheと違うのは、ページをまたいでもデータが消えないこと、データ毎に有効期限を決められることです。
よって、主に有効期限を決めてデータを保持・管理する際に利用します。

Transients API の使い方

使い方はほぼ wp_cache関数 と同じです。データ・データの名前・有効期限をセットし、
必要になったらデータの名前を元に呼び出します。削除も可能です。

set_transient( $transient, $value, $expiration ) 第一引数はTransientの識別子、第二引数にデータ、第三引数に有効期限(秒)を渡すことで Transient を生成します。データは自動でシリアライズされます。
get_transient( $transient ) 第一引数に渡された識別子から、生成したTransientを取得します。存在しないか、有効期限が切れていた場合はFALSEを返します。0や空と識別するため存在チェックは === を使用するのがおすすめです。
delete_transient( $transient ) 指定された識別子の Transient をクリアします。

キャッシュを取得、なければキャッシュを生成する

下の例では負荷の高いクエリ結果をTransientとして保持させています。

<?php

// キャッシュキー設定
$cache_time = 60 * 60 * 24 * 3; //3日
$cache_key  = 'archive';

// キャッシュを受け取る
$posts = get_transient($cache_key);

// キャッシュが存在しない場合、セットする
if ( $posts === FALSE ):
	$arg = [
		// 負荷の高い内容
	];
    $posts = new WP_Query($arg);
    set_transient($cache_key, $posts, $cache_time);
endif;

...

if ($posts->have_posts()):
	while ($posts->have_posts()):

		//

	endwhile;
endif;

?>

get_transient() でキャッシュを取得し、FALSEであればキャッシュを生成しています。
この例では受け取った $posts は記事ループに使用するデータとしています。

これでキャッシュが実装できました。
負荷の高いものであればあるほど二度目のアクセスが高速化したことを体感できると思います。

ですが、このままでは $posts に該当する記事が更新されても有効期限が来なければ反映されない状態になってしまいます。

キャッシュをクリアする

Transientはwp_cacheと違い、一度セットすれば有効期限が来るまで削除されないキャッシュです。
そのため記事の一覧をキャッシュする場合、記事の登録・更新・削除タイミングでキャッシュをクリアする必要があります。

アクションフックを使うことで希望するタイミングにキャッシュクリアを差し込むことができます。

functions.php

<?php

// 投稿状態変更時のキャッシュクリア
function clear_cache($new_status, $old_status, $post) 
{
    delete_transient('archive');
}
add_action('transition_post_status', 'clear_cache_to_publish', 10, 3);

?>

上記例はシンプルに「投稿の状態が変更された時にキャッシュをクリアする」といった内容ですが、
状態別、カテゴリ別で処理を振り分けることも可能です。

WordPressはカスタムフィールドなど便利で多機能ですが、増やせば増やすほど負荷がかかってしまいます。適度にキャッシュを使って軽量化させてサクサクサイトを目指しましょう。

php WordPressのカスタマイズ

関連記事