WordPress: Transients APIを使ってREST APIなどの結果をキャッシュしてみる

WordPressはWebページが表示される度に本体プログラムが実行されます。
毎回同じ結果になる可能性が高い処理、例えばREST APIなどで得た結果をDB等に保存しておいて、一定期間が経過するまでそちらを見た方が効率的なケースがあります。
つまりキャッシュしておくということですね。

WordPressは任意の値をキャッシュする機能が標準であるので、使ってみようと思います。

Transients API

WordPressにはTransients APIという機能が用意されています。

このAPIのset_transient()関数を使うと、任意の値をキャッシュできます。
get_transient()関数で、キャッシュした値を取得します。

事前準備など不要なので、とても簡単です。

キャッシュのセット:set_transient()

set_transient( $transient, $value, $expiration );

  • $transient:キャッシュの名前
  • $value:キャッシュする値
  • $expiration:キャッシュの有効秒数。0なら無期限

成功するとtrueが、失敗するとfalseが返ってきます。
キャッシュする値は、自動で文字列に変換されてDBに保存されます。

キャッシュの取得:get_transient()

get_transient( $transient );

  • $transient:キャッシュの名前

データが無かったり、期限が切れているとfalseが返ってきます。
データが無いのか、それとも値がfalseなのか判断できないので、キャッシュする値にfalseを使用しない方がいいですね。

使用例

次のコードは、WordPressのREST APIを使用して最新記事データを5件取得しています。

  • function get_rest_api_result(){
  • $transient_name = 'my_rest_api_result';
  • $result = get_transient( $transient_name );
  • if( $result === false ){
  • // 最新記事を5件取得
  • $url = "http://xxxx.xxx/wp-json/wp/v2/posts?per_page=5";
  • $result = mb_convert_encoding( file_get_contents($url),"utf-8","auto");
  • $result = json_decode($result);
  • set_transient( $transient_name, $result , HOUR_IN_SECONDS);
  • }
  • return $result;
  • }
AFFS Simple Code Viewer
Copy

get_transient() の結果がfalseならキャッシュが存在しないので、記事データを取得してキャッシュに保存します。

file_get_contents()は、引数として与えられたURLにアクセスして結果を受け取ります。
どんな結果になるかは、ドメイン部分をご自分のWordPressサイトに変更してブラウザでアクセスしてみてください。

得られる結果はJSONという形式のテキストデータです。
これはjson_decode()関数でオブジェクトに変換して使用します。
キャッシュには変換後のオブジェクトをセットしています。
こうすることでget_transient()関数は、オブジェクトを返すようになります。

set_transient()の第三引数の HOUR_IN_SECONDS は、WordPressが用意している時間に関する定数です。
一時間の秒数が定義されています。

最後に、取得したオブジェクトコードを返して終了です。

なお上のコードは REST API から正常にデータを取得できたかどうかのチェックをおこなっていません。
file_get_contents()関数でエラーが出ていないかチェックする処理が必要ですね。

作成した関数のテストとして、次のようなショートコードを用意しました。

  • add_shortcode('get_newpost','get_newpost');
  • function get_newpost(){
  • $newpost = get_rest_api_result();
  • foreach ( $newpost as $key =>$value){
  • $title = esc_html($value->title->rendered);
  • echo "[{$key}]{$title}<br>";
  • }
  • }
AFFS Simple Code Viewer
Copy

記事に [get_newpost] と記述すると、ショートコードが呼び出されるはずです。

キャッシュの削除:delete_transient()

キャッシュをリセットしたり、不必要時に削除したりするときは、delete_transient()関数を使用します。

delete_transient( $transient );

  • $transient:キャッシュの名前

キャッシュが存在していたらtrue、存在していなかったらfalseを返します。

キャッシュデータの保存先

キャッシュしたデータは、データベースの wp_optionsテーブルに保存されます。

set_transient()関数を呼び出すと、このテーブルに次の二つのレコードが作成されます。

内容 フィールド名 備考
option_name option_value
データレコード _transient_キャッシュ名 シリアライズ(テキスト化)されたデータ
タイムアウトレコード _transient_timeout_キャッシュ名 有効期限 無期限でないときのみ

見てわかるようにデータを保存するレコードと、有効期限を保存するレコードが作成されます。
ただしset_transient()関数の3番目の引数が0のときは、タイムアウトレコードは作成されません。

有効期限はUnix タイムスタンプです。
例えば 1649746236 という値なら、date()関数を使って、

echo date('Y-m-d H:i:s',1649746236);
// 2022-04-12 15:50:36

となるので、2022年4月12日の15時50分36秒までが有効期限となります。

Transients APIのフック

補足として、今回紹介した関数のフィルターやアクションフックを抜粋してみます。

set_transient()

set_transient()関数の構文が次のようになっているとき、関数内で呼び出されるフィルターとアクションは以下の表のようになっています。

構文:set_transient( $transient, $value, $expiration )

フック名 タイプ タイミング 引数 内容
pre_set_transient_{$transient} フィルター キャッシュ前 $value, $expiration ,$transient $valueを変更するフィルター
expiration_of_transient_{$transient} フィルター キャッシュ前 $expiration ,$value, $transient $expirationを変更するフィルター
set_transient_{$transient} アクション キャッシュ後 $value, $expiration, $transient $transient別のアクション
setted_transient アクション キャッシュ後 $transient, $value, $expiration return前に実行されるアクション

get_transient()

get_transient()関数の構文が次のようになっているとき、関数内で呼び出されるフィルターとアクションは以下の表のようになっています。

構文:get_transient( $transient )

フック名 タイプ タイミング 引数 内容
pre_transient_{$transient} フィルター キャッシュ取得前 false, $transient 取得値の事前フィルター
transient_{$transient} フィルター キャッシュ取得後 $value, $transient リターン値を変更するフィルター

取得値の事前フィルターで最終的な値がfalseになると、キャッシュの有無の判定が行われずにフィルターの結果がリターンされます。

delete_transient()

delete_transient()関数の構文が次のようになっているとき、関数内で呼び出されるフィルターとアクションは以下の表のようになっています。

構文:delete_transient( $transient )

フック名 タイプ タイミング 引数 内容
delete_transient_{$transient} アクション キャッシュ削除前 $transient 事前アクション
deleted_transient アクション キャッシュ削除後 $transient 事後アクション

事後アクションは、キャッシュが存在していて削除されて時のみ呼び出されます。