2015年8月19日、 WordPress バージョン 4.3 “Billie” が公開されました。
なんでもジャズミュージシャンの Billie Holiday から命名されているそうですが、その”Billie”もとい 4.3 にアップデートをすると画面が真っ白になる不具合が発生しています。特に WP-Ban プラグイン が入っている場合は要注意!!です。WP-Ban のバージョンにより確実に真っ白画面になります。
バージョンによる動作状況
WordPress 4.3 + WP-Ban 1.65 の組み合わせでは確実に真っ白画面になります。
また WordPress 4.2.4 以下 + WP-Ban 1.66 の組み合わせでは WP-Ban プラグインを有効化できません。
WP-Ban | |||
---|---|---|---|
バージョン | 1.65 | 1.66 | |
WordPress | 4.2.4 以下 | 正常 | 有効化不可 |
4.3 | 真っ白画面 | 正常 |
原因
真っ白画面 (WordPress 4.3 + WP-Ban 1.65)
したがって WordPress 4.3 + WP-Ban 1.65 の組み合わせの場合、以下のような関数の二重定義エラーとなり、画面が真っ白になります。
関数の二重定義エラー
in /wp-content/plugins/wp-ban/wp-ban.php on line 249
[/cc]
WordPress 4.3 – general-template.php
/** * Gets the language attributes for the html tag. * * Builds up a set of html attributes containing the text direction and language * information for the page. * * @since 4.3.0 * * @param string $doctype Optional. The type of html document. Accepts 'xhtml' or 'html'. Default 'html'. */ function get_language_attributes( $doctype = 'html' ) { $attributes = array(); if ( function_exists( 'is_rtl' ) && is_rtl() ) $attributes[] = 'dir="rtl"'; if ( $lang = get_bloginfo('language') ) { if ( get_option('html_type') == 'text/html' || $doctype == 'html' ) $attributes[] = "lang=\"$lang\""; if ( get_option('html_type') != 'text/html' || $doctype == 'xhtml' ) $attributes[] = "xml:lang=\"$lang\""; } $output = implode(' ', $attributes); /** * Filter the language attributes for display in the html tag. * * @since 2.5.0 * @since 4.3.0 Added the `$doctype` parameter. * * @param string $output A space-separated list of language attributes. * @param string $doctype The type of html document (xhtml|html). */ return apply_filters( 'language_attributes', $output, $doctype ); }
/** * Displays the language attributes for the html tag. * * Builds up a set of html attributes containing the text direction and language * information for the page. * * @since 2.1.0 * @since 4.3.0 Converted into a wrapper for get_language_attributes(). * * @param string $doctype Optional. The type of html document. Accepts 'xhtml' or 'html'. Default 'html'. */ function language_attributes( $doctype = 'html' ) { echo get_language_attributes( $doctype ); }
WP-Ban 1.65 – wp-ban.php
### Function: Returns page's language attributes depends on WordPress language function get_language_attributes($doctype = 'html') { ob_start(); language_attributes(); $language_attributes = ob_get_contents(); ob_end_clean(); return $language_attributes; }
WP-Ban 有効化不可 (WordPress 4.2.4 以下 + WP-Ban 1.66)
関数未定義エラー
Fatal error: Call to undefined function get_language_attributes() in /wp-content/plugins/wp-ban/wp-ban.php on line 287
[/cc]
対応策
上記マトリクスから対応策を考えますと、以下の2点になるかと思います。
- WordPress 4.3 にアップデートする場合は、アッデート前にまず先に WP-Ban プラグインを 1.66 にアップデートしておいてから WordPress 4.3 にアップデートする。
- WordPress 4.2.4 以下の場合は WP-Ban プラグインは 1.65 のままにしておき、1.66 へはアップデートしない。
真っ白画面になってしまった場合 (WordPress 4.3 + WP-Ban 1.65)
あらかじめ、https://downloads.wordpress.org/plugin/wp-ban.1.66.zip をダウンロードし解凍しておきます。
WP-Ban 1.66 の wp-ban.php ファイルをアップロードする方法
- wp-ban.php ファイルのリネーム
WP-Ban 1.65 の /wp-content/plugins/wp-ban/wp-ban.php が真っ白画面になる原因のファイルですので、 FTP, SFTP, SSH やファイルマネージャーなど WordPress 非依存のツールを使い wp-ban.php を適宜 wp-ban.php.bak などの名前にリネームします。これで真っ白画面は解消されます。 - WP-Ban 1.66 の wp-ban.php ファイルのアップロード
解凍した WP-Ban 1.66 の wp-ban.php を /wp-content/plugins/wp-ban/ ディレクトリにアップロードします。
WP-Ban プラグインの削除&インストールする方法
- WP-Ban 1.65 プラグインの削除
FTP, SFTP, SSH やファイルマネージャーなど WordPress 非依存のツールを使い、プラグインのディレクトリ(/wp-content/plugins/)に入り、wp-ban ディレクトリごと削除します。これで真っ白画面は解消されます。 - WP-Ban 1.66 プラグインのインストール
解凍した WP-Ban 1.66 の wp-ban フォルダをすべてアップロードし手動でインストールするか、ダッシュボードのプラグインから新規追加で「プラグインのアップロード」にて wp-ban.1.66.zip ファイルを選択しインストールします。
もしくはダッシュボードのプラグインから新規追加で WP-Ban プラグインを検索し再インストールでもよいです。なお設定はデータベースにありますので消えることはありません。
WP-Ban有効化不可の場合 (WordPress 4.2.4 以下 + WP-Ban 1.66)
あらかじめ、https://downloads.wordpress.org/plugin/wp-ban.1.65.zip をダウンロードし解凍しておきます。
WP-Ban 1.65 の wp-ban.php ファイルをアップロードする方法
- wp-ban.php ファイルのリネーム
WP-Ban 1.66 の /wp-content/plugins/wp-ban/wp-ban.php が有効化不可になる原因のファイルですので、FTP, SFTP, SSH やファイルマネージャー(WordPress依存可)などのツールを使い wp-ban.php を適宜 wp-ban.php.bak などの名前にリネームします。 - WP-Ban 1.65 の wp-ban.php ファイルのアップロード
解凍した WP-Ban 1.65 の wp-ban.php を /wp-content/plugins/wp-ban/ ディレクトリにアップロードします。
WP-Ban プラグインの削除&インストールする方法
- WP-Ban 1.66 プラグインの削除
ダッシュボードのプラグインからバージョンが 1.66 の WP-Ban プラグインを一旦削除します。この場合、WP-Ban プラグインをアンインストールしますので設定は消えてしまいます。設定を消したくない場合は、別途 FTP, SFTP, SSH やファイルマネージャー(WordPress依存可)などのツールを使い プラグインのディレクトリ(/wp-content/plugins/)に入り、wp-ban ディレクトリごと削除します。 - WP-Ban 1.65 プラグインのインストール
解凍した WP-Ban 1.65 の wp-ban フォルダをすべてアップロードし手動でインストールするか、ダッシュボードのプラグインから新規追加で「プラグインのアップロード」にて wp-ban.1.65.zip ファイルを選択しインストールします。
おわりに
本体開発者からすれば「WordPress 4.3 リリース前に『プラグイン開発者はプレビュー期間で動作確認しておいてくれよ!』という時間は十分取った」とかいう後付け理由はすぐに思い浮かぶのですが、技術屋視点からしますと、結局被害を被るのは WordPress ユーザで、現に重大な不具合が起きているわけですから、本体への関数追加は充分に調査し慎重に行うべきであると思います。
一方、今回は、WP-Ban プラグイン開発者側にも大いに問題があると思います。WordPress 4.3 で真っ白画面になる不具合が、本体側起因と言えども、1.65 ⇒ 1.66 への対応で wp-ban.php の get_language_attributes() 関数をごっそり削除してしまうというヘタレ対応をしてしまいました。これでは下位互換が保てません。
WordPress 4.3 への WP-Ban 開発者の対応として、バッティングする get_language_attributes() 同名関数を「If you can’t beat them, join them.(長いものに巻かれよ)」ではないですがプラグイン側が折れて名前変更するとか、バージョンチェック処理を入れるとか、方法はいくつかあると思います。
例えば WP-Ban 1.66 で以下のような対応が必要であったと思います。1.67 でなにかしら対応してくれること祈ります。
function_exists() 関数で定義済かを事前確認する
if ( !function_exists('get_language_attributes') ) { function get_language_attributes($doctype = 'html') { ob_start(); language_attributes(); $language_attributes = ob_get_contents(); ob_end_clean(); return $language_attributes; } }
呼び出し元の関数を get_language_attributes() から language_attributes() に変更する
'<html xmlns="http://www.w3.org/1999/xhtml" '.language_attributes().'>'."\n".
default_template = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" <?php echo str_replace('"', '\"', language_attributes()); ?>>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=<?php echo get_option('blog_charset'); ?>\" />\n<title>%SITE_NAME% - %SITE_URL%</title>\n</head>\n<body>\n<div id=\"wp-ban-container\">\n<p style=\"text-align: center; font-weight: bold;\"><?php _e('You Are Banned.', 'wp-ban'); ?></p>\n</div>\n</body>\n</html>";
WordPress 4.3 本当に “Billie” 敬意を表してるんでしょうか。こんなんでは “Billie” が泣いてますよね! Billie is Crying!
2015/08/25 追記
普段は PHP 使いではないので WordPress ってこんなに簡単にFatal(真っ白)で落ちるのかって思う反面、Plugin Framework というアーキテクチャの観点からすると、 WordPress 本体がプラグインをロードするロジックで、関数の二重定義ぐらい 本体側でチェックしてよねって思ってしまうのは私だけではないはず。この機能さえあれば、例え今回のような関数の二重定義があったとしても、プラグインは動作不可にはなっても WordPress 本体が落ちてしまい、ダッシュボードなどの管理画面にすらたどり着けないという致命的なエラーは起こらないはずです。
いまさら感いっぱいの「整形ルール」などの実装より、このような信頼性を高める機能改善のほうがよっぽどプライオリティが高い気がします。