【WordPress】サイト更新日をキーとして重い処理をキャッシュする
更新日:2023/03/31
WordPressはブラウザから要求があるたびにWebページを作成しています。
それは、サイドバーなど固定部分も含まれます。
固定部分にはカテゴリ一覧や新規記事一覧など、作成するために重い処理が必要なものがあります。
結果が毎回同じになるのに、同じことを繰り返すのはムダですね。
そこで今回は、処理した結果をキャッシュしておき、サイトの記事が更新されたらキャッシュを再生成するような仕組みを作成します。
仕組みの概要
今回作成する仕組みの概要です。
サイト更新日の取得
サイトの投稿が最後に更新された日付、つまりサイト更新日はget_lastpostmodified()で取得します。
この関数については、次のページで紹介しているので参考にしてみてください。
この関数は更新日を文字列で返すのですが、そのままデータベースにセットします。
以降は、get_lastpostmodified()の結果とデータベースの値を文字列のまま比較します。
そのため、サイト更新日が巻き戻ってもキャッシュの更新処理がおこなわれます。
データベースの仕様
キャッシュはWordPressデータベースのoptionsテーブルに次の二つのレコードを生成して、管理します。
●更新日レコード: get_lastpostmodified()の結果を保存
●データレコード: キャッシュ内容を保存
これは、一定時間のキャッシュ管理を行えるWordPressのTransients APIを参考にしています。
■【WordPress】一定時間データをキャッシュしてレスポンス時間を短縮する方法
サイト更新日でキャッシュする関数コード
仕組みの概要から、次のコードを作成しました。
function get_my_site_cache( $key , $callback , $arg ){
$key_date = '_my_site_cache_date_' . $key . '_';
$key_value = '_my_site_cache_value_' . $key . '_';
$last_modified = get_lastpostmodified('gmt');
if( get_option($key_date) === $last_modified){
$result = get_option($key_value);
if( false !== $result) return $result;
}
$result = call_user_func($callback, $arg);
update_option($key_date, $last_modified, false);
update_option($key_value ,$result, false);
return $result;
}
上のコードは、引数の型チェックなどを行っていないので必要なら追加してください。
この関数は3つの引数を受け付けます。
- $key: 他と重複しない文字列
- $callback: キャッシュ無効時にデータを生成する関数
- $arg: $callbackに渡す引数
Transients APIはキャッシュ無効のときに『無効である』という戻り値を返すので、データを作成してキャッシュにセットします。
少々面倒な手順が必要です。
そこで、キャッシュが無効のときはデータを生成してキャッシュしてから値を返すような流れにしました。
使用例:最新記事のキャッシュ
作成した関数の使用例です。
最新記事の一覧を生成してキャッシュします。
// キャッシュからデータを取得して最新記事リスト(liタグ)を取得
function get_new_entry_list( $page_num = 5 ){
$entries = get_my_site_cache( 'my_new_entry_list' , 'create_new_entry_data' , $page_num );
$count = 1;
$result = '';
$url = $name = '';
foreach($entries as $e){
switch( $count ){
case 1:$url = esc_url($e);break;
case 2:$name = esc_html($e);break;
case 3:
$result .= '<li><a href="'.$url.'">'
. $name .'</a>('.esc_html($e) . ')</li>';
$count = 0;
}
$count ++;
}
return $result;
}
// キャッシュ無効時のデータ生成
function create_new_entry_data( $page_num ){
$args = array(
'posts_per_page' => $pageNum
);
$result = [];
$posts = get_posts( $args );
foreach ( $posts as $post ){
$result[] = get_permalink( $post->ID );
$result[] = $post->post_title;
$result[] = $post->post_modified;
}
return $result;
}
キャッシュするデータは、次のような配列です。
[ URL , タイトル , 更新日 , URL , タイトル , 更新日 , ... ]
タグを生成してキャッシュしてもよさそうですが、今回はこのような形式にしました。
この関数をウィジットから呼び出します。
class My_Newpost_Widget extends WP_Widget {
function __construct() {
parent::__construct('My_Newpost_Widget', 'My最新記事','My最新記事' );
}
public function widget( $args, $instance ){
echo $args['before_widget']
.$args['before_title'] . '最新記事' . $args['after_title']
.'<ul id="new_entry">'
.get_new_entry_list(5).'</ul>'
.$args['after_widget'];
}
public function form( $instance ) {
}
public function update( $new_instance, $old_instance ) {
return $new_instance;
}
}
add_action( 'widgets_init', function(){
register_widget('My_Newpost_Widget');
} );
これで、サイトの記事が更新したときのみデータ生成するサイドバーウィジットの完成です。
更新日:2023/03/31
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。