プライム・ストラテジーの森下です。
今回のテーマはWordPressのキャッシュ機構の1つTransientAPIについて
のお話していきたいと思います。
キャッシュとは
みなさんご存知の通りキャッシュとは一度使ったデータを取り出しやすいところに置いておき 次から素早く使えるようにする仕組みのことです。図1のようなイメージです。
一言にキャッシュといっても様々な種類のキャッシュが存在します。TransientAPはデータベースのキャッシュになります。このキャッシュはデータベースに問い合わせて取得したデータをデータベース内に一時的に保存する仕組みです。
TransientAPIは外部サイトから取得した情報やウェブサイト内で横断的に表示されている情報をキャッシュするのには適したキャッシュ機構です。横断的に表示されている情報とはヘッダーやサイドバー、フッター等全ページで同じ情報を表示している箇所を意味しています。
それではTransientAPIはどのように仕組みか説明します。
Transient APIの仕組みについて
ウェブサイトがページを表示するのには図2のようにクライアントがリクエストをサーバーへリクエストを送り、PHPがDBへ取得したい情報を取得するために問合せ、取得したデータをPHPが表示するという流れになります。
図2

この時キャッシュしたい部分をset_transientを用いてwp_optionsにキャッシュします。使い方は以下のようになります。Transientの名前とはTransientを取得する際に用いるキーになります。これはユニークでなくてはなりません。注意点としてはTransientの名前は長さ 45 文字以下という制約があるところです。
set_transient( "Transient の名前", "キャッシュしたいデータ", "キャッシュする時間" )
そしてキャッシュした情報を取得するときは
get_transient( "Transientの名前" )
で取得することができます。また、キャッシュしたデータを消したいときは
delete_transient( "Transientの名前" )
で消すことができます。それでは続いて具体的な使い方を説明します。
実践編
ここでは実際どのように使用すればいいのかというのを説明したいと思います。
まず横断的に表示されている情報をキャッシュしてみましょう。下記のソースコードはheader.phpのファイルに記述されているものと考えてください。
<?php
・・・
if( ! $header_cache = get_transient( 'header_cache' ) ):
ob_start();
?>
<header>
//グローバルメニュー表示等の記述
</header>
<?php
$header_content = ob_get_clean();
set_transient( 'header_cache', $header_content, )
else:
echo $header_cache;
endif;
?>
・・・
次は外部サイトから取得した情報をTransientAPIでキャッシュする場合のソースコードを紹介します。下記は関数になりますので、書いただけでは動作しませんので表示したい箇所にこの関数と引数を記述してください。
<?php
function transient_test($url, $expiration = 3600) {
$cache_key = external-information';
/**
* 既にキャッシュされているかどうかを判定
* キャッシュされていればキャッシュを取得して表示する
* キャッシュされていなければset_transientでwp_optionsに保存する
*/
if ( ! ($response_body = get_transient($cache_key)) ) {
/** wp_remote_getはWordPressの関数で引数にしたURLにGETメソッドを使用して
* HTTPリクエストからの生の応答を取得することができます。
*/
$response = wp_remote_get($url);
/**
* エラーの発生がなくステータスコードが200の場合の分岐
if( !is_wp_error($response) && $response["response"]["code"] === 200 ) {
/**
* レスポンスボディを変数$response_bodyに格納し、set_transientでwp_optionsに保存する。
*/
$response_body = $response["body"];
set_transient($transient, $response_body, $expiration);
} else {
$response_body = false;
}
}
return $response_body;
}
?>
このように使用することで、キャッシュされていなければset_transientでデータを保存し、次からはそのキャッシュしたデータを表示することでウェブサイトを高速化させることが出来ます。また第二引数にキャッシュ保持期間を指定することが出来ますので、使用箇所によって柔軟に保持期間を決めることが出来ます。
また、下記のようにクエリをキャッシュをすることも出来ます。キャッシュ名はユニークである必要がありますのでsingleの後ろに記事IDを付与しています。
<?php
// キャッシュ名
$cache_key = 'single-'. $post->ID;
// キャッシュを受け取る
$custom_query = get_transient($cache_key);
// キャッシュが存在しない場合、セットする
if ( $custom_query === FALSE ):
$arg = [
// meta_query等の負荷の高い抽出条件
];
$custom_query = new WP_Query($arg);
//HOUR_IN_SECONDSとはWordPressにて定義されており1時間を意味します。
set_transient($cache_key, $custom_query, HOUR_IN_SECONDS);
endif;
if ($custom_query->have_posts()):
while ($custom_query->have_posts()):
//出力
endwhile;
endif;
?>
しかしTransientは一度セットすれば有効期限が来るまで削除されないキャッシュですので記事を更新しても更新される前の情報が表示されてしまいます。そのため何かの契機でキャッシュをクリアされる必要があります。下記は記事を更新するとdelete_transientを実行してキャッシュをクリアにするソースコードです。
<?php
// 投稿状態変更時のキャッシュクリア
function clear_cache($new_status, $old_status, $post)
{
delete_transient('archive');
}
add_action('transition_post_status', 'clear_cache_to_publish', 10, 3);
?>
これで記事を更新することでキャッシュがクリアされちゃんと更新情報を表示されます。
TransientAPIはウェブサイトを高速化する上でとても有効的且つ使いやすいので、是非上記の方法や上記を参考にオリジナルのロジック作成など試してみてください!
今回はいかがでしたでしょうか。今後新規サイト構築やサーバの引っ越しを考えられている方がいらっしゃいましたら、是非日本に大規模なデータセンターを構え、手厚いサービスをしてくれることで定評のある鈴与シンワートの「S-Port」クラウドを導入してみてください。
また、併せてKUSANAGIというWordPressサイトをキャッシュ未使用でも高速化を可能とするサービスも是非使ってみてはいかがでしょうか。
ご興味がある方は以下をご参照ください。
https://s-port.shinwart.com/service/eva/kusanagi/

