WordPressのデバッグでログを見ているとPHP Warning行が邪魔に感じることがあるかもしれません。探しているのはエラーを引き起こすError行だけだったりするからです。しかしphp.iniやPHP-FPMの設定をいくら直しても消えないのは、WordPressが原因だったのです。
WordPress関連ログに現れる“PHP Warning”
WordPressで問題が起きた時に、調査のためログを見ます。その際、以下のようなPHP Warningを消したいと思ったことはありませんか。
PHP Warning: Undefined array key "REQUEST_METHOD" in
/hoge/wp-content/plugins/flying-scripts/html-rewrite.php on line 18
PHP Warning: Declaration of CASConditionPlaceholder::filter_excluded_context($posts) should be compatible with WPCAModule_Base::filter_excluded_context($posts, $in_context = false) in /hoge/wp-content/plugins/content-aware-sidebars/conditio変数の未定義とか、PHPのバージョンが変わったことによる互換性の警告とか、あるいは自分が触れないWordPress本体やプラグインのWarningが大量に出たりします。
PHPやPHP-FPMのエラーレベルを変えても効かない問題
Linux触った事がある人ならこれはエラーレベルの設定だなということで、PHPやPHP-FPMのerror_repporting設定を変更するわけですが、何故か効かない。これに困った方も多いのではないかと思います。
実はこれ、PHPの設定は正しく読み込まれています。問題はその後、WordPress本体の初期化時に error_reporting()
関数を呼び出して、エラーレベルを上書きしていることにあります。
WordPressの wp-includes/load.php にある wp_debug_mode() という関数が犯人です。この関数は WP_DEBUG
の値に応じてエラーレベルを強制的に設定します。
- WP_DEBUG = true → E_ALL(全レベル)
- WP_DEBUG = false または未定義 → E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR
つまり WP_DEBUG = false でも E_WARNING は有効なままです。そしてWordPressには Error だけに制限する設定は用意されていません。
「じゃあ wp-config.php で @ini_set(‘error_reporting’, E_ERROR) を書けばいいのでは?」と思うかもしれませんが、これも効きません。wp-config.php は wp_debug_mode() より前に読み込まれるため、せっかく設定しても後から上書きされてしまいます。
また、wp-config.php の @ini_set(‘error_reporting’, E_ERROR) は wp_debug_mode()より前に実行されるので、設定しても上書きされ無効な設定となります。
これが、php.ini、PHP-FPM、wp-config.php のどこで設定しても PHP Warning が消えない理由です。
解決方法はmu-plugin
WordPressが起動するまでの手順を追うと、以下のとおりです。
1. PHP起動 → php.ini / php.d/*.ini を読み込み
2. wp-config.php を読み込み(ini_set はここで実行される)
3. wp-settings.php → wp_debug_mode() を呼び出し
→ error_reporting() で強制上書き ← ここで全部リセットされる
4. プラグイン・テーマの読み込み
つまり、1と2でいくら設定しても、3で上書きされます。これを解消するには、WordPress の初期化より後にエラーレベルを再設定すればよいので、mu-plugin(Must-Use Plugin)を使います。
mu-plugin は wp-content/mu-plugins/ ディレクトリに .php ファイルを置くだけで自動的に読み込まれるプラグインのことです。管理画面での有効化は不要で、通常のプラグインより先に、かつ wp_debug_mode() より後に実行されます。
mu-pluguin設定手順
wp-content/mu-plugins/ ディレクトリに以下のファイルを作成します。ファイル名はなんでもよいです。set-errorlebel.phpとかなんとか。
<?php
/**
* Plugin Name: Custom Error Reporting
* Description: wp_debug_mode() による error_reporting 上書きを再設定し、Fatal エラーのみをログに記録する。
*/
error_reporting(E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR);これだけです。ファイルを置くだけで、WordPress の上書きをさらに上書きして、Fatal エラーのみログに記録されるようになります。
確認方法
mu-plugin が読み込まれているかは、WP-CLI で確認できます。
wp plugin list --status=must-use
エラーレベルが正しく設定されているかは、以下で確認できます。
wp eval "echo error_reporting();"
# 出力例: 69(= E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR)
まとめ
この問題が厄介なのは、原因がわかりにくいことです。PHPの問題だと思い込んでいる限り、WordPress本体が設定を上書きしているとはきづきにくい罠があります。「WordPress error_reporting override」で検索すれば情報は見つかりますが、そもそも WordPress を疑って検索しなければたどり着けません。
