WordPress6とphp8.1とDebug modeとDeprecatedと
Contents
このサイトのサーバーはロリポップです。これは以前のページでも何回も書いていることです。ちなみにロリポップのスタンダードプランです。スタンダードプランでも、WordPress のサイトにおいて、Chrome DevTools lighthouse で、どれでもいつでもではないけれど満点を出せるので十分に速いのです。より速くするためにいろいろと思いついたことを試す環境として、これぐらいがちょうど良いのです。そのロリポップにおいて php 8.1 のモジュール版が使えるようになったとのこと。php 8.1 の CGI版はすでに使用できるようになっていたけれど、あえてまだ使用せずに php 8.0 で動かしていたのです。
WordPress 6.0 においては、php 8.1 に完全に対応しているわけではなく、いくつもの Deprecated が排出されるのはローカル環境において確認していましたね。エラーではなく、Deprecated なのでプログラムの挙動に問題はなく、無視して使用してもよかったのではあるけれど、余計なものが排出されているとそれだけでも足かせになるような気がして、踏み切れずにいたのですね。
WordPress において php 8.1 に完全対応してくれるアップデートを今や遅しと待ち受けていたのだけれど、どうもまだまだ先の事のようです。と、聞こえてきたのが php8.1 のモジュール版の方。とりあえず、Deprecated は気にしないことにして、php 8.1 のモジュール版を使いたくてしょうがなくなってしまったのですね。どれくらい速くなっているのか楽しみにしていたのですから。
WordPress のデバッグモード WP_DEBUG と error_reporting
公開しているサイトの場合、php のエラー表示はさせないように、サーバーの php.ini か .htaccess において display_errors を off に設定しているのは常識的なこと。ページに表示はさせないけれど、log_errors を on に、error_log にログファイルのアドレスを設定すれば、php で出てはいけないエラーを知ることができます。
ただし、WordPress を普通に使用している状況においては、Notice や Deprecated までもを含めたすべての告知を知ることができるわけではありません。WordPress を起動して Notice、Deprecated までもを含めたすべての告知を把握するためには、通常では WordPress を Debug mode にしなくてはいけないのです。これは wp-config.php において WP_DEBUG を true にすれば Debug mode となり、WP_DEBUG_LOG も true にすることでエラーログも残すことができるようになります。そしてこの場合の error_reporting の値は E_ALL となります。
なぜ、Debug mode にしないとすべてのエラーを知ることが出来ないのかというと、WP_DEBUG が false の場合、告知させるエラーのレベルを設定する error_reporting の値が WordPress によって上書き設定されるからです。このあたりのことは、wp-includes/load.php の function wp_debug_mode() にあります。
なお、WP_DEBUG が false のときにここで設定されるエラーレベルは下のとおり。
整数値で示すと 4983 ということになります。この設定だと、なるほど Notice も Deprecated も排出されないのはわかります。error_reporting の各引数をつないでいる演算子「 | 」はビット演算子のビット和です。どちらかのビットが 1 なら 1 というやつです。or 的なものです。そう、これは php においては上記のようにビット値を定数として定義済みなので、わかりやすい文字列で指定することができるのですが、これが、.htaccess においては整数値によって指定しなくてはいけなくなります。と、言ってもなんら難しいことではありません。ちなみにその定義済み定数の詳細なページはここ -> 「php.net 定義済み定数」
ビット和だの難しいことを考える必要などありません。下表を見てのとおりで、設定したいエラー項目の整数値をただ足し合わせればいいだけのことです。全部足し合わせれば E_ALL の 32767 になります。ビット和にしても難しいことではないのです。ただ設定したい項目の位を 1 にすればいいだけのことです。逆に Deprecated だけを無視させたいならば、E_ALL において、E_DEPRECATED で 1 になっている位だけを 0 にすればいいだけのことです。これを式で示すと E_ALL & ~ E_DEPRECATED となります。でも、.htaccess においては設定に使用するのは整数値なので、たんに 32767 – 8192 = 24575 で良いという具合です。
余談ですけれどね、自分はこのあたりのことを、 「php.net ビット演算子」 で学んでいたのですが、実際に数値をあてはめて確かめていたりなどしていたのです。が、どうにも値の具合がへんてこで、これはいったいとなってしまったわけなのです。まさかこのような公式のページで数値に誤りがあるとは想像できませんでしたので。いやぁ~、間違っているはずなどないですよね?でもやっぱりへんだしね、E_ALL のビット値がね、自分のほうがおかしいのでしょうかね、どうにも。まぁ、そんなことはいいかって。
wp-config.php での error_reporting() と ini_set()
WordPress とは全く関係なく、サーバーの機能として、php.ini か .htaccess で log_errors と error_log を設定することにより、指定したログファイルに php エラーをログさせることができるのは、先にも書いたことです。しかし、ここで問題にしているのは、WordPress の Debug mode を false にしていると、WordPress によって error_reporting を変更されてしまうので、WordPress で発生する Notice やら Deprecated をログさせることが出来ないということです。
.htaccess により error_reporting を設定したところで、WordPress が読み込まれ load.php で設定されるのはその後なので、WordPress を使う場合には全く意味のないものになってしまうということです。それでは、WordPress の Debug mode を false のまま、すべてのエラーを把握することは不可能なのか?と、いうことになります。
いえいえ、そんなことはありません。試してみたところ簡単に対処できました。wp-config.php の最後に php の関数 error_reporting() を追加することで設定できました。こんな具合に。これはまぁ、functions.php に書いても同じことではないかとは思います。ちなみに、ini_set() も php から php.ini の設定を変更できる関数で、この場合、エラーログファイルのアドレスを変更しています。こうすれば、その WordPress で出てしまったエラーだけを分けてログさせることができます。
ただし、php8.1 で動かしているならば、特に管理画面において、いまだたくさんの Deprecated を見なくてはいけない状況です。正直、ログにリストされたたくさんの Deprecated を見るのは、もううんざりしてしまいます。
その場合は、ログイン画面や管理画面においては error_reporting の設定を変更することで対処することができました。同じく wp-config.php の最後に付け加えたものを以下のようにしています。
アクセスされた url において、文字列の先頭から4文字が ”/wp-” で、そのあとに ”admin-ajax.php” を含んでいれば、E_ALL。”wp-admin” もしくは ”wp-login” を含んでいれば、E_ALL & ~ E_DEPRECATED に設定する、ということになります。これにてログイン画面、管理画面においての Deprecated はログされなくなりました。
一般のサイトアクセスは、最初の if 条件文ではじかれるので、パフォーマンス的にはそんなに影響はないと思います。なお、サブディレクトリに WordPress がインストールされている場合は、このままでは全く意味をなしません。例えば、WordPress が wp フォルダにインストールされているならば、
と、こんな具合です。面倒ならば strpos() でもいいかとは思いますが、思わぬところで合致することなどあるやもしれませぬゆえ。
あと、error_log におけるログファイルの設定においては、上記の場合は、ローカル環境においてのものです。これがレンタルサーバーだとちょっとややこしいのかもしれません。この部分、先述した wp-includes/load.php の function wp_debug_mode() においては、こんな具合になってます。
WP_CONTENT_DIR は WordPress の wp-content フォルダになりますゆえ、これを使うのも手かと思います。
php error_get_last()
これとはべつに、php にはエラーを取得する方法が他にもあります。その1つが error_get_last() 関数。この関数については以前にも記事にしています。最後に発生したエラーしか取得できませんが、手軽に使えるというのが最大の利点。あと、error_reporting の設定の影響を受けないので、すべての告知を取得することができます。
そしてサーバー側での php error_log では、そのエラーが出たときにアクセスしていた ip address は知るすべはないのですが、error_get_last() はその ip address を紐づけてログすることができるのです。結構、エラーが出ているときには、クローラーなどがおかしなアクセスをしていることが多かったりするのです。
サーバー側での php error_log で得られる告知は、だいたい error_get_last() でも得ることができますが、いつも5,6個が関係してまとめて発生するエラーなどは、当然のこと、最後の1つだけしか得ることができません。
で、逆に、なぜかはよくわからないのですが、error_get_last() だけで知ることができる告知というものがあるのです。まぁ、それも Deprecated なわけですが。
DEPRECATED : Unknown: Use of mbstring.internal_encoding
と、いうことで、これにて知りたい全てのエラー通知を、WordPress の Debug mode を使わなくても、ログファイルで見れることになったわけなのです。Warning などの問題のあるエラーはほぼ対処ずみなので、見ることになるのは php8.1 による Deprecated ばかりになります。
それらをネットで調べていくと、すでに知られているものばかりではありますし、こちら側でどうこうするべきものでもなさそうです。
その中で、ちょっと気になったものが1つ。それが、
DEPRECATED : Unknown: Use of mbstring.internal_encoding is deprecated : Unknown : 0
と、いうもの。同じようなものがもう一つあり、
DEPRECATED : Unknown: Use of mbstring.http_input is deprecated : Unknown : 0
なるもの。
これら2つとも、アクセスすると必ず告示されるというものでもないようで、アクセスによって出たり出なかったりするようです。そしてこれら2つの Deprecated は、WordPress を介さないページにおいても出ていたので、WordPress とは無関係ということになります。
実はこれら2つの Deprecated は サーバー側での php error_log では全く告知されることはなく、error_get_last() でのみ、得られたものです。この理由は自分にはよくわかりません。一体、なぜなのだろう。
ところで、この mbstring.internal_encoding の Deprecated はネットをめぐれば、これもすでに情報はたくさんあって、php8.0 から削除された設定項目の mbstring.internal_encoding を設定しているがゆえに出るものとのこと。まぁ、Deprecated で表示される内容を見てもそういった事をうかがわせます。
phpinfo() でその設定を確認してみると、たしかに mbstring.internal_encoding の Master Value の値は UTF8 となっていて設定してあることを示していました。ちなみに mbstring.http_input の値も pass となっていて設定してあるようです。
確認のために、php8.1 モジュール版を CGI版に変更して同じ Deprecated が告示されるかをためしてみたところ、一度たりとも出ることはなかったのです。CGI版の方を phpinfo() で確認してみると、やはりというか、その Master Value の値は no value となっていて、設定していないことを示していました。
と、いうことから、やはりこれら2つの Deprecated が モジュール版において出現するのは、どうやらその設定がしてあることが原因に思えます。これ、ローカルで再現させてみようと思い、php8.1 でmbstring.internal_encoding の設定をしてみると、php 自体が使えなくなってしまったのです。なので、この現象を再現させることはできませんでした。php.ini じゃないところで設定しているのだろうか?
しかし、Master Value と・・・?そもそも php8 の php.ini においては、デフォルトでそれらの設定はコメントアウトされているし、説明書きもしっかりとあるので、わざわざコメントアウトをはずすということも考えづらいのではありますけれど。
実はこのあたりのことを、サポートにメールしたのですが、phpinfo() をそれが書いてあるファイルの phpinfo.php としてしまったりで、自分の説明が悪くちゃんと意図がつたわらなかったようで、サポートセンターのフォーマットに従った問題の説明を求めるメールがきましたね。しかし、もう一度確認のためにいろいろとやっていたことと、再度、説明を書くのがどうにも煩わしく、どうせ Deprecated なことだし、と、そのまま止まってしまっています。はてさて、面倒ですね、どうしたものか。
Post : 2022/07/29 18:43
Comments feed
Trackback URL : https://strix.main.jp/wp-trackback.php?p=171441