【WordPress】Transientを問答無用で無効化する…ことはできなかった!

Transientをもりもり使用したテーマを構築した際、問題になるのは「変わらないんだけどキャッシュなの?バグなの?」というお客様からの質問。
お客様もわかりづらいし、私たちも調査などなどで時間を使ってしまいます。

管理者としてログインしているときにはフロントのTransientを効かせないようにすればいいんじゃないか?ということで、そんなことができるのかとコアファイルを覗いてみました。


[追記:2018/06/19]プラグインが公式プラグインディレクトリに掲載

ダッシュボードからボタン一つで全てのTransientがクリアできるプラグイン「Clear Transient From Dashboard」が公式ディレクトリに掲載されました。

get_transient()では返り値を一括制御できない

Transients APIについてはこちらを参照。
get_transient()で既にキャッシュされている値を取得、有効期限を確認して、期限が切れていたら値を作り直してset_transient()、切れていなかったら取得したキャッシュの内容を使用する…というのが基本の使い方。
Transientを効かせないというのは、「常にget_transient()がfalseを返せばいい」ということ。
それならと、うまいフィルターがないかどうか確認。

フィルターはいくつかあるけど、全てフィルター名に$transientを使っている…。
$transientにはTransientの名前が格納されているので、Transientの名前ごとにフックをかけていかなければならない…フィルターを使用して一括で返り値を変更するのは難しそう。

オブジェクトキャッシュも一枚噛んでる

また、wp_using_ext_object_cache()の分岐も注目。オブジェクトキャッシュも絡んできているよう。
wp_cache_get()の中を少し遡ってみたけど、フィルターはなさそうだったので、ここでfalseが返せないとオブジェクトキャッシュ使用時はアウトですね。

うーん…これはどっかのタイミングで$_wp_using_ext_object_cacheをfalseに差し替えれば大丈夫そうかな?

get_option()でもどうにもできない

get_transient()内では返り値をfalseにはできなさそうだった…ということで、最後の砦、get_option()のフックを探してみる。
get_transient()内で、$transient_option = ‘_transient_’ . $transient; からの $value = get_option( $transient_option ); なので、get_option()に渡るときには、Transient名は全て ‘_transient_’ から始まるようになっている(DBを覗いたことがある人は、このコードを見なくても既に知っているかも)。
私の大嫌いな正規表現で「オプション名が’_transient_’ から始まったら false を返すよ!」ってしてあげればいいのでしょう。

…ということで、get_option()を覗いてみたのですが、あったフィルターはこちら!

もれなく$option!
SQL文で値を取得して、それをreturnしているので、これ以上遡ることは不可。なんということでしょう。

残念な結論

結論:一括なんてするな!Transient名ごとにフックしろ!
add_filter()で正規表現使えたり、フック増えたりすると嬉しいのだけど…ここまで拘っているということは、一括フィルターは用意する気なんてないよってことなんでしょうね。
おとなしくTransient名ごとにフックを書いてあげるしかないみたいです。


You Might Also Like