2019-07-23

rewrite_rules_array がタイミング依存で実行されない

WordPressにはパーマリンク機能があるんだけどそれは内部のrewrite_ruleとかい機能実装されている

そんで、rewrite_ruleはまぁ文字の通り書き換えルール何だけど、リクエストパスを良きように読み替えてくれる機能です。

んで、どうやってrewrite_ruleを書き換えるかと言うと、add_filter で 'rewrite_rules_array' にルールを追加するのが一般的っぽいです。

それを更新するために $wp_rewrite->flush_rules() を実行するんだけど、これ実は、アクセスごとに実行しては行けない機能っぽい。下記みたいな記事でinitフックで実行する用例がネット上には転がってるんだけど、これを鵜呑み実装するとバグる

https://qiita.com/M-Ikezawa/items/22d24455f776065865ea

wpdocs.osdn.jp にすらこの方法が書かれてるの…まずくね?

https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/WP_Rewrite

具体的にどうバグるかと言うと、rewrite_rules_array に設定した関数ときどき実行されません。

なんで rewrite_rules_array に登録した関数が呼ばれないかと言うと、WP_Rewrite::wp_rewrite_rulesっていうメソッドの中でget_option('rewrite_rules') して、DBに保存していたルールがなければ、新規ルール作成するっていう処理をしている。その新規ルール作成する処理ってのの一環でrewrite_rules_arrayに登録した関数も呼ばれます

まぁこDBアクセスしているのが怪しいですね。怪しいんですよ。そのものズバリflush_rules()を実行するとこのDB値を一旦削除して、ルールを作り直すっていう処理が動くんです。

なので並列アクセスしていると、DBの中身が作成されたり削除されたりといった動作が繰り返され、「flush_rules()実行しているのに、rewrite_rules_arrayに登録した関数が呼ばれない」といった動作になります。つまりバグます


flush_rules() 実行する代わりに、パーマリンクの設定を更新するべきだった

そもそも rewrite_rules_array に登録された処理はアクセスごとに実行されるべきものではありません。WordPressでのリライトルール上記の通りDB管理されていて、DBに保存されたものを使い回すので、rewrite_rules_array の実行は一度だけ行われれば十分になるような処理を書くべきです。rewrit_ruleは処理が重いので毎回ルールを書き換えるような利用は想定外なのでしょう。

そして rewrite_rules_array に登録した関数を変更したら、WordPressパーマリンク設定で設定を変更するボタンを押せば、処理内部でflush_rules()が実行され、rewrite_rules_array に登録した関数の処理が適用されます

rewrite_rules_array 登録関数で動的にルールを作りたい。

できるといえばできるけど、毎回アクセスごとに動作させるのがNGとなると実質出来ないってことになります。rewrite_ruleで対応するのは諦めましょう。

記事への反応(ブックマークコメント)

ログイン ユーザー登録
ようこそ ゲスト さん