管理画面で有効にしたプラグインが表のページで動かない:自作の APCu のオブジェクトキャッシュが古い設定を覚えていた

広告WordPress・PHP を学べる本

Amazonのアソシエイトとして、WordPress functions.phpは適格販売により収入を得ています。

管理画面からプラグインを入れて有効にしたのに、公開側のページでは何も変わりませんでした。同じプラグインを入れたほかのサイトでは、すぐに効いています。ログインしたまま公開側のページを開いたら効くようになったので、キャッシュが怪しいと考えて調べました。

原因:管理画面と公開側のページで、キャッシュの扱いが違った

このサイトには、APCu を使うオブジェクトキャッシュ(wp-content/object-cache.php)が入っていました。中を読むと、次のような作りになっていました。

このオブジェクトキャッシュの作り

  • 管理画面ではキャッシュを使わない(ふつうの DB の読み書きだけ)
  • 公開側のページでは、読んだ値を APCu に期限なしで覚える
  • ログインした人が公開側のページを開いたときだけ、APCu を全部消す

WordPress は、有効なプラグインの一覧(active_plugins)などの設定を、まとめてオブジェクトキャッシュに入れて使います。管理画面でプラグインを有効にすると、DB の値は変わります。ところが、公開側のページは APCu に覚えた古い一覧を使い続けるので、新しく有効にしたプラグインが読み込まれていませんでした。

確認のしかた

「プラグイン」の画面の「ドロップイン」に object-cache.php があれば、オブジェクトキャッシュを使っています。管理画面で変えた設定が公開側のページに出ないときは、ログインしていない状態でページを開いて確認、そのあとログインしたまま公開側のページを 1 回開き、もう一度ログインしていない状態で確認します。これで直るなら、オブジェクトキャッシュに古い値が残っていたということです。

直し方

すぐに直すなら、ログインしたまま公開側のページを 1 回開くだけです。ただ、毎回それを覚えておくのは大変なので、設定を変えたときにキャッシュを消す処理を足しました。管理画面ではこのオブジェクトキャッシュが読まれないので、APCu の関数を直接呼びます。

// プラグインの有効・無効や設定の保存のあとに、APCu のキャッシュを消す
// (管理画面と公開側のページで同じ APCu を使っている環境のときに効く)
function my_clear_apcu_after_change() {
	if ( function_exists( 'apcu_clear_cache' ) ) {
		apcu_clear_cache();
	}
}
add_action( 'activated_plugin', 'my_clear_apcu_after_change' );
add_action( 'deactivated_plugin', 'my_clear_apcu_after_change' );
add_action( 'upgrader_process_complete', 'my_clear_apcu_after_change' );

サーバーによっては、PHP の動き方の都合で、管理画面と公開側のページで APCu を分けて持っていることがあります。その場合は上のコードでは消えないので、ログインしたまま公開側のページを開くやり方が確実です。

気をつけること

  • オブジェクトキャッシュは、入れた本人も忘れがち。サイトを引き継いだら、まず「ドロップイン」を見ておく
  • 期限なしで覚える作りは速い反面、こうした食い違いが起きやすい。期限を付けるか、変えたときに消す処理を必ずセットにする
  • ページのキャッシュ(WP-Optimize など)とは別のものなので、ページのキャッシュを消しても直らない

SiteBeacon(サイトビーコン)

サイトが止まったら、すぐに気づける。

ホームページを 5 分ごとにチェックして、止まったとき・エラーが出たとき・SSL やドメインの期限が近いときに、メールでお知らせします。2 サイトまでは、ずっと無料で使えます。

SiteBeacon を見る サイトを直す相談をする

監視で気づいたあとの直す作業も、同じ担当がお受けします。