PHP8対応: E_WARNINGを黙々と直す
PHP7.4のサポートも終了したので、PHP7からPHP8系への切り替えのお問い合わせをいただくことが増えてきました。
個人的な印象としては、PHP7で動作していたシステムであればPHP8でも少ない修正で動作することが多いです。 Laravelのようなフレームワークを使っている場合は、それらの更新も必要になりますが、フレームワーク上に構築されているシステム自体は、少し直せば動作するようになることが多い印象です。
PHP8からは文字列と数値の比較結果が変更になっていたりと互換性のない変更はいろいろありますが、これらにひっかかることは、経験上あまりありませんでした。
下位互換性のない変更点
https://www.php.net/manual/ja/migration80.incompatible.php
それならPHP7からPHP8への移行は楽勝かというとそうでもありません。
「PHP5からPHP8への移行は何が面倒なのか」の記事と重複しますが、PHP7からPHP8への切り替えで一番面倒と感じるのは、一部のE_NOTICEレベルのメッセージがE_WARNINGに変更になったことです。
今まで、E_NOTICEなら無視でいいやと error_reporting(E_ALL & ~E_NOTICE); のようにして無視していた場合、PHP8からはE_WARNINGがぼろぼろ発生することになります。
経験上以下の警告がぼろぼろと出てきます。
- 未定義の変数を読み取ろうとした(Undefined variable)
- 未定義のプロパティを読み取ろうとした(Undefined property)
- 未定義の配列のキーを読み取ろうとした(Undefined array key)
仕事として受ける以上、E_WARNINGは修正しておくことをおすすめしていますが、これらの警告が出ても動作上は問題ないので、ログに出力されるだけなら(安くしたいので)修正しなくていいというお客さまもいます。
ですが、 https://wiki.php.net/rfc/engine_warnings のVoteをみると例えば、Undefined VariableについてはE_ERRORにすべきと考えている人がかなりいるようです。
このため、これらのE_WARNINGについても、将来バージョンにおいてはE_ERRORになる可能性も考えられるので、今のうちにE_WARNINGは取り切っておくのがよいと思います。
実際修正するとなると、Undefined variable/property警告は静的解析ツールで見つけ出すことができるので修正はそれほど手間ではありません。
一方、Undefined array key警告は静的解析ツールで洗い出すことはできないので(*1)、配列アクセスしている箇所を洗い出してチェックしたり、各機能を動作確認しながらチェックして修正をしていく形になります。
E_NOTICEに無頓着にコーディングされたものを後から消し切るのは非常に手間がかかります。保守契約していただけるものは、とりあえず一通り修正後、運用しながらログを監視してWarningが出力されたら都度直していく形にしています。そうでない単発のご依頼では、正常に動作するようになるところまでの修正はお約束しますが、E_WARNINGの修正はできるところまでとさせていただいています。納品後、何ヶ月かはログの監視&修正をお約束する形もできますが、いずれにしても期限を切っての対応となります。
Laravelを使っていると
ところで、LaravelではE_NOTICEが発生しても処理が停止します。 このため、error_reporting(E_ALL & ~E_NOTICE);として無視しているケースも多く見かけます。
PHP8に切り替えてE_WARNINGが出るようになると、それが原因でシステムが停止してしまうようになります。とりあえずerror_reporting(E_ALL & ~E_NOTICE & ~E_WARNING)のようにE_WARNINGも無視することで動かすこともできますが、これだと警告がログにも残らないのでやりすぎな感があります。
そこで、「Laravelでスクリプトを停止させずE_NOTICEのログを残す」で以前書きましたが、こちらの記事に書いた修正を行うことで、システムを停止させずにE_NOTICEやE_WARNINGをログを残すことができるようになります。このようにすれば、開発環境では厳密にチェックしつつも、運用環境では動作を止めず、運用しながらE_NOTICE/E_WARNINGのログを監視して問題があれば修正していくことが可能になります。
まとめ
長々と書きましたが以下まとめです。
- PHP8ではE_NOTICEレベルのメッセージがE_WARNINGになったものがある。
- もともとE_NOTICEに無頓着なコーディングをしていたものはPHP8で大量の警告が出ることになる。
- 特にUndefined array key警告は洗い出して修正するのが面倒。
- 動作上問題なかったとしても、E_NOTICE,E_WARNINGは修正しておきましょう。きっと将来のためになる。
(*1) phpstanやPhpStormの静的解析では検出できません。何か設定だったり別のツールがあったりするのかもしれませんが。
投稿日:2023/01/07 23:50