WordPress 4.7 にしたらWPが500で死ぬようになったりした

まぁBatcacheなんて日本で使ってる人居ないですよね……

追記:
WP4.7.2で修正されたREST APIの深刻なバグはこっち↓

WP4.7 のREST APIの深刻なバグについて ~検証環境~

先週末ぐらいから WordPress 4.7 の Beta1 がリリースされています。

WordPress 4.7 Beta 1

まあ Twenty Seventeen とか含まれるようになってるほか、やっとこさWP-REST-APIが含まれるようになるなりしています。詳しくは毎度のことねんでぶさんがいい感じにまとめてくれているので参考に。

WordPress 4.7 をチェックしています


WP 4.7 にすると真っ白

で、いつもどおり(beta以前から4.7のdev版を適用さしていたサイトにおいて)最新版をインストールしたのですが……

真っ白
真っ白 (画像はイメージです)

真っ白。

真っ白というかChromeが500のエラーをちゃんと表示してくれてますが……まぁブラウザによってはだいたい真っ白ですね。

全てのページにおいて発生するわけではないですし、管理画面とかは正常に表示出来るんですがまあトップページ含め個別ページとかが基本的に全滅。だめじゃん。

ちなみにマルチサイトでだったけど何故かメインサイトだけは問題ないかったみたい。謎が謎を呼ぶ……

で、ともかくエラーログをみてみる。
(最初ちゃんとエラーが測れなくて詰んでた)

なんかよくわからないけど 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_filteradd_actionを通じて操作するのだが、稀にしていない場合がある。(実行タイミングによってはadd_filterが使えなかったんかな)

で、このフック周り、WP_Hooksなのだが、4.7にて仕様が大きく変わったらしい。

WP_Hook: Next Generation Actions and Filters

で、直接触っているようなコードが含まれている場合互換性の問題が生じる。上記のように突然そこでエラーになるわけ。

もし貴方がプラグイン作者で直接触るようなコードを書いていた覚えがあるのならば、4.7がリリースされるまでに早急に修正するべき。

で、結局問題のプラグインは……?

目星がついたのでgrepかけてみたら一発で見つかった。

そもそもこれで引っかかったのが大体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が使えるようになったはずなのでそれを使うコードに直しましょう。

コメントを残す