まぁBatcacheなんて日本で使ってる人居ないですよね……
先週末ぐらいから WordPress 4.7 の Beta1 がリリースされています。
まあ Twenty Seventeen とか含まれるようになってるほか、やっとこさWP-REST-APIが含まれるようになるなりしています。詳しくは毎度のことねんでぶさんがいい感じにまとめてくれているので参考に。
WP 4.7 にすると真っ白
で、いつもどおり(beta以前から4.7のdev版を適用さしていたサイトにおいて)最新版をインストールしたのですが……

真っ白。
真っ白というかChromeが500のエラーをちゃんと表示してくれてますが……まぁブラウザによってはだいたい真っ白ですね。
全てのページにおいて発生するわけではないですし、管理画面とかは正常に表示出来るんですがまあトップページ含め個別ページとかが基本的に全滅。だめじゃん。
ちなみにマルチサイトでだったけど何故かメインサイトだけは問題ないかったみたい。謎が謎を呼ぶ……
で、ともかくエラーログをみてみる。
(最初ちゃんとエラーが測れなくて詰んでた)
1 2 3 4 5 6 7 8 9 10 |
[30-Oct-2016 18:41:52 UTC] PHP Fatal error: Uncaught Error: Call to a member function apply_filters() on array in ………/wp-includes/plugin.php:203 Stack trace: #0 ………/wp-includes/functions.php(1084): apply_filters('status_header', 'HTTP/1.0 200 OK', 200, 'OK', 'HTTP/1.0') #1 ………/wp-includes/class-wp.php(685): status_header(200) #2 ………/wp-includes/class-wp.php(736): WP->handle_404() #3 ………/wp-includes/functions.php(955): WP->main('') #4 ………/wp-blog-header.php(16): wp() #5 ………/index.php(17): require('/var/www/vhosts...') #6 {main} thrown in ………/wp-includes/plugin.php on line 203 |
なんかよくわからないけど apply_filters('status_header', 'HTTP/1.0 200 OK', 200, 'OK', 'HTTP/1.0')
辺りでエラーが出てるらしい。知るかいな……
とりあえず原因がよく分からなくわからなかったけどとりあえず4.6.1に戻せば普通に表示できる。バグか〜?
どうせしばらく放置しておけばそのうちなおってるとか思って待ってみたものの変化なし。とくにバグとしても登録されていない。どうやら自分がおかしいっぽい。
そう思っても何が原因か検討もつかなかったのでcoreのSlackに特攻してみた。
「上記みたいなエラーが出るんだけどこれって既知の問題?」
みたいなことを。
返事は5分もせずにリードデベロッパーのRyanから返事が返ってきた。
「もしかして
$wp_filter
をダイレクトに編集してるんじゃない?」
と。
WP_Hooks が変わった
$wp_filter
は WordPress のフィルターやフックを保持しているグローバル変数(!!!!)なのだが、おそらく普通は直接触るなんてことはないと思う。というかしていないのが正解。普通はadd_filter
やadd_action
を通じて操作するのだが、稀にしていない場合がある。(実行タイミングによってはadd_filterが使えなかったんかな)
で、このフック周り、WP_Hooks
なのだが、4.7にて仕様が大きく変わったらしい。
で、直接触っているようなコードが含まれている場合互換性の問題が生じる。上記のように突然そこでエラーになるわけ。
もし貴方がプラグイン作者で直接触るようなコードを書いていた覚えがあるのならば、4.7がリリースされるまでに早急に修正するべき。
で、結局問題のプラグインは……?
目星がついたのでgrepかけてみたら一発で見つかった。
1 |
grep -R '$wp_filter' wp-content |
そもそもこれで引っかかったのが大体bbpressとかbuddypress, woo, jetpackとかの方面ばかりだったのだけどその中、/wp-content/advanced-cache.php に$wp_filter['status_header'][10]['batcache']
というズバリなものを発見。そう、Batcacheを使ってたんです。
Batcacheは出力をMemcacheにキャッシュしてくれる便利なAutomattic製プラグイン、なんだけどどうやらこれに使われていたらしい。
試しにこれを無効化してみると確かにエラーが出なくなった。
このことを報告すると、pentoが「既に動くコードあるよ!」みたいなこと教えてくれた。これ:batcache#76
どうやら既に同様の報告があったらしいけどプラグインディレクトリにあるのはまだ更新されていないっぽい。GitHubから最新のmasterを落としてきてadvanced-cacheを上書き。
これでアクセスしてみたところ、無事エラーが出ずにキャッシュも効いてページが表示できるようになりました。めでたしめでたし。
まとめ
もしなんか理由があって$wp_filter
を直接触るコードを書いている人は、おそらく今回のでadd_action/filter
が使えるようになったはずなのでそれを使うコードに直しましょう。