WordPress 4.3 アップデートで画面が真っ白 WP-Ban プラグインには要注意!

LINEで送る
Pocket

2015年8月19日、 WordPress バージョン 4.3 “Billie” が公開されました。

なんでもジャズミュージシャンの Billie Holiday から命名されているそうですが、その”Billie”もとい 4.3 にアップデートをすると画面が真っ白になる不具合が発生しています。特に WP-Ban プラグイン が入っている場合は要注意!!です。WP-Ban のバージョンにより確実に真っ白画面になります。

バージョンによる動作状況

WordPress 4.2.4, 4.3 と WP-Ban 1.65, 1.66 バージョンによる動作状況を以下のマトリクスで示します。
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 で general-template.php に get_language_attributes() 関数が追加されました。この get_language_attributes() という名前の関数は、すでに以前から同名の関数が WP-Ban に実装されており 1.65 まで存在していました。
したがって WordPress 4.3 + WP-Ban 1.65 の組み合わせの場合、以下のような関数の二重定義エラーとなり、画面が真っ白になります。

関数の二重定義エラー

[cc] Fatal error: Cannot redeclare get_language_attributes() (previously declared in /wp-includes/general-template.php:2624)
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 );
}
この get_language_attributes() 関数は、 WordPress 4.2.4 までは、ほぼ language_attributes() という関数名でした。ですので正確にはリネーム(リファクタリング)ですかね。なお language_attributes() 関数のコメントには以下の記載があります。
/**
 * 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)

一方 WordPress 4.2.4 以下の場合、WP-Ban 1.66 では get_language_attributes() 関数が削除されたため、関数がない旨の未定義エラーで WP-Ban プラグインを有効化できません。

関数未定義エラー

[cc] 重大なエラーを引き起こしたため、プラグインを有効化できませんでした。

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)

WP-Ban 1.65 のまま、WordPress 4.3 にアップデートしてしまった場合は真っ白画面になり、ダッシュボードなどの管理画面にもアクセスできません。したがって別途 FTP, SFTP, SSH やファイルマネージャーなど WordPress 非依存のツールが必要になります。方法は主に以下の2通りになります。
あらかじめ、https://downloads.wordpress.org/plugin/wp-ban.1.66.zip をダウンロードし解凍しておきます。

WP-Ban 1.66 の wp-ban.php ファイルをアップロードする方法

  1. 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 などの名前にリネームします。これで真っ白画面は解消されます。

  2. WP-Ban 1.66 の wp-ban.php ファイルのアップロード
    解凍した WP-Ban 1.66 の wp-ban.php を /wp-content/plugins/wp-ban/ ディレクトリにアップロードします。

WP-Ban プラグインの削除&インストールする方法

  1. WP-Ban 1.65 プラグインの削除
    FTP, SFTP, SSH やファイルマネージャーなど WordPress 非依存のツールを使い、プラグインのディレクトリ(/wp-content/plugins/)に入り、wp-ban ディレクトリごと削除します。これで真っ白画面は解消されます。

  2. 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)

WordPress 4.2.4 以下で、WP-Ban 1.66 にアップデートしてしまった場合、有効化できませんがダッシュボードなどの管理画面へのアクセスはすべて可能ですので、いわゆる WP-Ban プラグインのダウンデートを行います。方法は主に以下の2通りになります。
あらかじめ、https://downloads.wordpress.org/plugin/wp-ban.1.65.zip をダウンロードし解凍しておきます。

WP-Ban 1.65 の wp-ban.php ファイルをアップロードする方法

  1. 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 などの名前にリネームします。

  2. WP-Ban 1.65 の wp-ban.php ファイルのアップロード
    解凍した WP-Ban 1.65 の wp-ban.php を /wp-content/plugins/wp-ban/ ディレクトリにアップロードします。

WP-Ban プラグインの削除&インストールする方法

  1. WP-Ban 1.66 プラグインの削除
    ダッシュボードのプラグインからバージョンが 1.66 の WP-Ban プラグインを一旦削除します。この場合、WP-Ban プラグインをアンインストールしますので設定は消えてしまいます。設定を消したくない場合は、別途 FTP, SFTP, SSH やファイルマネージャー(WordPress依存可)などのツールを使い プラグインのディレクトリ(/wp-content/plugins/)に入り、wp-ban ディレクトリごと削除します。

  2. WP-Ban 1.65 プラグインのインストール
    解凍した WP-Ban 1.65 の wp-ban フォルダをすべてアップロードし手動でインストールするか、ダッシュボードのプラグインから新規追加で「プラグインのアップロード」にて wp-ban.1.65.zip ファイルを選択しインストールします。

おわりに

今回は、以前からプラグイン側にある関数と同名の関数を WordPress 本体側が 4.3 で実装(追加)してしまったのが原因でした。まあ WordPress 本体開発者からすればプラグイン側の関数名など眼中にないのかもしれませんが、そこは grep などで調査し、本体側に追加する関数に同名の関数がプラグイン側に存在した場合は、すみやかにプラグイン開発者側に周知するなり知らせるのがマナーかと思います。プラグイン開発者軽視、本体開発者側の傲慢もそこにはあるのかもしれません。

本体開発者からすれば「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() 関数で定義済かを事前確認する

function_exists() 関数で get_language_attributes() 関数がすでに定義済かどうか事前に確認し下位互換を保持する。
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() に変更する

1.66 と同様に WP-Ban 側の get_language_attributes() は削除し、代わりに呼び出し元の get_language_attributes() を WordPress 4.3 にも 4.2.4 以下にも存在する 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 本体が落ちてしまい、ダッシュボードなどの管理画面にすらたどり着けないという致命的なエラーは起こらないはずです。
いまさら感いっぱいの「整形ルール」などの実装より、このような信頼性を高める機能改善のほうがよっぽどプライオリティが高い気がします。

「WordPress 4.3 アップデートで画面が真っ白 WP-Ban プラグインには要注意!」への16件のフィードバック

    1. この件に関して WordPress ユーザは 1mmも非はないと思いますよ。間違いなくこれは WordPress と WP-Ban 側の問題だと思います。
      開発者側で十分予見できたにも関わらず、WordPress ユーザが重大な被害を被るアップデートってそれはもう開発者の仕事ではないと思いますね。

      今回は重大&公共性の観点から緊急に記事をリリースにしました。

  1. Googleで検索してここにたどり着きました。私も一昨日自分の管理サイトでこれなりました。ロリポップレンタルサーバーを使用しているのですが、ロリポップの管理画面にFTPツールというのが有って、ここからpluginsフォルダを開く→wp-banフォルダの名前を_wp-banに変更した所ダッシュボードにアクセス出来るようになり、ダッシュボードからwp-banを削除しました。wp-banの更新も確認出来たのですが、ちょっと様子見です。

    1. ご報告ありがとうございます。

      そうですね、原因は wp-ban.php ファイルですから、この「/wp-content/plugins/wp-ban/wp-ban.php が存在しない」いう対応を行えば真っ白画面が解消されます。ですので_wp-banフォルダへのリネームでも構いません。ただしダッシュボードから wp-ban プラグインを削除(アンインストール)しますと設定も消えてしまいますのでその点だけはご注意ください。

  2. この記事には、本当に感謝です。8月19日に WordPress 4.3 への
    更新に失敗して、何日も復旧に取りかかる気力が湧かないままでした。
    昨日、やっと復旧作業に取りかかる中で、この記事にめぐりあえて、
    実質、30分足らずで、WP-Ban と、WordPress の両方の更新に
    成功しました。ありがとうございました。

  3. 私のブログも真っ白に!同じサーバー上の別ドメインのWPサイトは4.3にアップデートしておらず無事だったので、最悪の場合再インストールしてバックアップ復元かな?と思ったのですが、こちらの記事のお陰で数分の作業で復旧しました。ありがとうございます。本当に助かりました。

    1. ご報告ありがとうございます。お役に立ててなによりです。

      話は変わりますが、当該ブログ拝見致しました。TOEICの点数が凄い!
      http://ishulife.com/
      サッカーや野球観戦で、実質オッサンになってから海外デビューした私には、もっと若い頃に海外を五感で感じておくべきだったと今更ながら痛感しております(汗)海外渡航って、自己投資と同じですよね。

  4. はじめまして。
    今朝、お客さんからWP4.3にアップグレードしたら動かなくなった・・・と泣きつかれ、こちらにたどり着きました。
    アップグレード前に何かしましたか?と聞いてもよく判らないの一点張りで、どうしようかなと思ってたんですが、記事に書かれてますとおり、WP-BANを1.66にバージョンアップしたら正常に動きました。

    本当にありがとうございました・・・!!(感涙)

    1. ご報告ありがとうございます。こちらこそお役に立ててなによりです。

      個人サイトであれば自己責任で済みますが、クラアイントとなるとなにかと大変ですよね。
      > 何かしましたか?と聞いてもよく判らないの一点張りで、
      私も今まで何度か経験してます(笑)

  5. とても助かりました!
    この記事に出会えたおかげで原因&解決方法がすぐにわかり一瞬で直りましたm(_ _)m

  6. ワードプレス4.3アップデート後に管理画面含めすべてが真っ白になりパニック状態に・・・

    何とか解決策はないものかとgoogleで鬼検索しまくっていたらこちらの記事に辿り着きました。

    おかげ様で画面真っ白状態は解消し正常に作動しております。これでようやく安眠できそうです。

    本当にありがとうございました。大変感謝しております。今後共ブログ拝見させていただきますのでよろしくお願い致します。

    1. ご報告ありがとうございます。
      お気持ちお察しします。画面が真っ白は本当に焦りますよね。
      こちらこそお役に立ててなによりです。

  7. ありがとうございます!
    あなた様の記事のおかげでようやくサイトを復旧することができました。
    もう諦めるしかないかと思っていました……。
    本当に感謝しております。ありがとうございました!!

コメントを残す

メールアドレスが公開されることはありません。