WordPress5.6は、直前にメジャーバージョンが上がったばかりのPHP8への対応を始めました。
メジャーバージョンが変わっただけに、変更点もなかなかのものになっています。
結論からいうと、PHP8に完全対応するのは大変。サードパーティ製のテーマ・プラグインを使っている人はとくに。
(ほとんどそうだと思うけど。)
PHP8対応の大変さ
PHP8は5年ぶりのメジャーアップデートです。
メジャーバージョンの変更は下位互換しないのを許しているので、PHP7で正常なプログラムがエラーになることも覚悟しないといけません。
WordPress本体(WordPress Core)は開発チームにおまかせするしかありませんが、テーマ・プラグインも対応が必要です。
WordPress.orgのコミュティー以外はWordPress公式リポジトリにあっても第3者作成(サードパーティ製)です。各開発者が対応しないといけません。
WPバージョンに未対応のテーマ・プラグインでも使えることがありますが、WP5.6がPHP8に対応を始めたので、これからはそうはいきません。
少なくともWP5.6以上に対応しているものを使うようにしましょう。
今回は、WP5.6のフィールドガイドに書いてあることを解説していきます。
といっても、動くものは動く。
ただ、これまでよりも動かなくなるリスクは高いですよってこと。
PHP8の互換性とは?
まずはじめに、WordPressが考えるPHP8との互換性について触れています。百聞は一見にしかずなので、翻訳します。
Significant effort has been put towards making WordPress 5.6 compatible with PHP 8 on its own, but it is very likely that there are still undiscovered issues remaining.
WordPress 5.6をPHP 8と互換性を持たせるためにかなりの努力をしてきましたが、まだまだ未発見の問題が残っている可能性が高いです。
筆者訳
(いきなり誰だ? このおっさんは。)
Because of the nature of WordPress usage and the commitment to our user base, compatibility is to be considered in the eyes of those users. The goal is to elevate the broader ecosystem to a state that is compatible with PHP 8. That requires that the Core software not just be compatible on its own, but also provides defenses against common problems seen in the transition to PHP 8, while continuing to function on older versions of PHP.
WordPress の利用の性質上、またユーザーベースへのコミットメントのため、互換性はユーザーの目線で考えなければなりません。目標は、より広範囲のエコシステムをPHP 8と互換性のある状態に昇格させることです。そのためには、Core ソフトウェアがそれ自体の互換性だけでなく、PHP 8 への移行時に見られる一般的な問題に対する防御策を提供しつつ、古いバージョンの PHP で機能し続けることが求められます。
筆者訳
It also should be acknowledged that WordPress is never used in isolation (without any theme or plugins), so WordPress itself being able to run on PHP 8 does not indicate “full” compatibility.
また、WordPress は決して単独で(テーマやプラグインなしで)使用されているわけではないことを認識しておく必要があり、WordPress 自体が PHP 8 で動作することは「完全な」互換性を示すものではありません。
筆者訳
The state of PHP 8 support within the broader ecosystem (plugins, themes, etc.) is impossible to know. For that reason, WordPress 5.6 should be considered “beta compatible” with PHP 8.
より広範囲のエコシステム(プラグインやテーマなど)の中での PHP 8 のサポート状況を知ることは不可能です。そのため、WordPress 5.6 は PHP 8 との「ベータ互換性」があると考えるべきでしょう。
筆者訳
WordPressはCMSのプラットフォームを提供しているだけで、各種機能はテーマ・プラグインに任せられています。その特性を考えれば、ベータ版にしたいという理由も分かります。
というか、それなら永遠にベータ版ってことになると思う。WordPress.orgのリポジトリから、PHP8とPHP7で動くもの以外を消していく強権発動を出さない限り。
完全な互換性を作っていくのはWordPressユーザーになります。互換性のあるテーマ・プラグインを選ぶのはユーザーだから。
ベータ互換性
さっきも強調していた『ベータ版』について項目を作っています。『しつこい』とも思いますが、それだけ大事ですよってことでしょう。
ここでは全訳ではなくポイントだけを書きます。
WordPress本体( Core)は『完全な互換性』を主張できない。多くの時間が必要だから。
プラグインやテーマの開発者はPHP8と互換性のあるものにすることを求められている。
プラグイン・テーマ開発者の助けがあって、ユーザーに負担をかけることなく『完全な互換性』が達成できる。
だからWordPress Coreは助けを必要としている。
(ここではプラグイン・テーマ開発者に向けて言っている。)
自動テストや静的解析によって確認された互換性の問題は、後述しているものを除いてすべて対応済み。
それでもWordPress Coreの自動テストの範囲はもっと改善される必要がある。
いくつかの問題を発見するには細かな手動テストが必要。
PHP8にアップグレードする前に徹底的にテストすることを強くすすめる。
ポイントは、プラグイン・テーマは早くPHP8に対応する必要があるってことと、自動テストだけでなく徹底的な手動テストもしましょうってこと。
(もちろん、PHP8だけ動けば良いのではなく、PHP7までを今まで通りできつつPHP8でも動けるようにすること。)
また、自動テストには足りない点もありますが、後述されているところを除けばかなり対応されているということ。
じゃあ何が足りないんだ? というところは後述にまかせましょう。以降は、WordPressがPHP8に影響されるところの詳しい説明です。
PHP8の変更点
フィールドガイドの文言で気になるところが。
プラグインやテーマの開発者が注意しなければならない、コードの中で対応しなければならない PHP 8.0 の変更点を非網羅的にまとめてみました。
『非網羅的』って。取り残し、不足分はあるけどって言ってます。ベータ版の真骨頂でしょう。
あくまで修正のポイントであって、あとは個々でがんばってねってことです。
名前付きパラメータ
PHP8では、関数のパラメータに名前付きで指定できるようになりました。いくつかのメリットがあります。
どのパラメータを渡しているか分かりやすい。
パラメータの順序を気にしなくていい。
デフォルト値をスキップして指定できる。
<?php
// PHP < 8.0
$my_term = get_term( 1, '', ARRAY_A );
// PHP >= 8.0
$my_term = get_term( output: ARRAY_A, term: 1 );
もちろんですが、PHPの関数でも使えます。
<?php
// Using positional arguments:
array_fill( 0, 100, 50 );
// Using named arguments:
array_fill( start_index: 0, count: 100, value: 50 );
WordPressでは使ってはいけない
フィールドガイドでは、名前付きパラメータについて問題点を指摘しています。
今後、すべてのPHPコードに重要な下位互換性の考慮事項を導入する。
これによりパラメータ名はAPIの一部になり、将来パラメータ名を変更すると下位互換性が失われる。
(古いパラメータ名を使うと致命的なエラーになる。)
APIの一部とは、たとえばクラスのプロパティのように決め打ちになることで、安易に変えられないということ。
クラスのpublicプロパティを参照するのに名称を変えられると困りますよね?
今後導入すると言ってるので、パラメータ名は下位互換性を考えて変わります。
WordPress Coreでは積極的に関数の見直しを行っており、パラメータ名が正しく、予約語を使ってないことを確認しているが、WP5.6の変更点ではない。
WP5.6では名前付きパラメータを明示的にサポートしていない。
下位互換性の考慮事項の監査が終了するまでオススメしない。
WordPressの関数やクラスで名前付きパラメータを使うときは自己責任で。
明示的にサポートしていないとは、『そりゃ使えるけど、将来エラーになっても知らんよ?』ということ。
(内容を見るにエラーが出る可能性は高い。)
監査が終了すると、パラメータ名がAPI化され変わるものじゃなくなるので、それまで待っててね? と言っています。
それは将来の開発者向けノートでアナウンスするとも。
PHPコアは、PHP8のリリースを見越して独自のパラメータ名の見直しを行っている。
その内容はドキュメントに反映されてないこともあり、ドキュメントに変更がある可能性がある。
たしかにこれもヘビーな内容ですが、PHP8がリリースされた今、あまりないんじゃないかと。
(個人の見解。)
人は間違うもので、あれだけのボリュームのドキュメントですからミスもあるでしょう。
まぁ、WordPressがサポートする前に落ち着いていると思うので、気にしなくていいかな?
(個人の見解2。)
内部関数の厳格な型/値の検証
内部関数とは、PHPに用意されている標準関数のこと。
PHP8から型宣言をしているパラメータでは、型が合わないと致命的なエラー(Uncaught TypeError)になります。
また、PHP8から内部関数で厳格な型宣言に変更されてものがあり、PHP7までは動いたり警告で済んでいたものがエラーになることもあります。
これはもう、エラーにならないよう直すしかありません。
結果から言うと、WP5.6では検証中でクローズがWP5.7の予定です。しばらく待ったほうが良いでしょう。
WordPressの型宣言
WordPressでは型宣言を使っていますが、declareの型チェックをしていません。
(型宣言だけして厳格にしていない。)
PHP8でもエラーにならないように防御策を行っているようですが、これが終わるまではType Errorが出るとも言っています。
そのチケット(#51423)のクローズ予定がWP5.7なので5.6ではエラーが出ることもあるでしょう。
ちなみにこの内容の内訳のチケット(#51525)もありますが、これもクローズ予定がWP5.7です。
絶対にPHP8では動かないとは言い切れませんが。
算術/ビット演算子のより厳密な型チェック
配列やクラスオブジェクトの算術演算、ビット演算で、ありえない計算をしているものはすべてエラーになります。
配列の足し算(+)は配列の結合になるので、これだけは例外で変化なし。
ありえない計算をすること自体バグなので、PHP8にアップグレードしたからといって影響することはないでしょう。
ただし、そのバグが無いという前提。
PHP7では計算としてはバグなんだけど結果を返すものがありました。その計算結果は意味のないもの。
WordPressでは、これらのありえない計算をしていなければ影響ないはず。
テーマやプラグインがPHP8に対応するまで待ち、カスタマイズした部分はそのあとテストしたほうがいいでしょう。
数値文字列
数値文字列の処理が、より直感的でエラーが発生しにくいように変更されました。
ほかの主な空白処理との一貫性から、数値文字列で末尾の空白が使えるようになっています。
影響するのはこんなところ。
- is_numeric() 関数
- 文字列同士の比較
- 型宣言
- インクリメント、デクリメント演算
変更点は小さいですが影響範囲は広いです。数値計算がからんでるところは要注意。
ただ、数値文字列をキャストや変換せずに数値計算する人はあまりいないので修正は小さそう。
(ふつうは数値文字列をそのまま計算に使わない。)
まさかと思いますが、WordPressではテーマやプラグインで計算間違いが起きる可能性があります。
個人的には『そんな計算してるやつが悪い』と思うので影響度は小さいと思う。(と思いたい。)
数値と非数値文字列のゆるい比較
個人的には、数値と文字列の比較はすべきでないと思います。比較の前に型を合わせて厳密な比較をするほうが安全だしバグになりにくいから。
WordPressでもそれは同じ。テーマやプラグインがPHP8の対応バージョンになるまで待ちましょう。
計算間違いが起きないとは言い切れません。
エラー、警告、通知の変更
PHP8のエラー、警告、通知が再分類されました。主に修正された目的はレベルの格上げ。警告をエラーに、通知を警告に変えたものが多くあります。
ふだんからログをチェックして、ログ出力を抑えるコーディングをしている人には影響ないですが、『通知や警告はエラーじゃないし動くからいいや』にしていた人は要注意です。
とくに警告を放置していたものはエラーになって処理が正常に動きません。
PHPの公式ドキュメントでは、すべてのエラー、警告、通知を網羅したものはありません。WordPressのドキュメントに主に出るであろうものがピックアップされています。
こちらにまとめました。
ビルド・テストツール関連の変更
ボクはPHPUnitを使ってないので、ドキュメントをかいつまんで和訳します。
(意訳、追記あり)
WordPressはPHP5.6.20以降をサポートしているので、PHPUnitをPHP8で実行するのはかんたんじゃありません。
(WordPressは古いPHPバージョンもサポート範囲に入っている。)
現在、PHP8をサポートしているのはPHPUnit >= 9.3 だけ。 |
PHP5.6をサポートしているのはPHPunit 5.7.xが最後。 |
PHPUnit 8.x では、値を返さないいくつかのメソッドについ て、戻り値の型として void を指定するようになった。しか し、この戻り値の型は PHP < 7.1 では使えない。 |
PHP 5.6でテストスイートを実行する機能を維持しつつ、PHP 8でもテストを実行できるようにするために、必要な PHPUnitの変更をWordPress Coreのテストスイートにバックポートし、Composer を使って PHPUnit 7.x のオートロード処理を行うようにしました。
(PHPUnitをWordPress Core(WP本体)に含めることができるらしい。)
WordPress CoreのPHPUnitテストスイートをPHP8で実行するには、インストールと実行にComposerが必要。
これを簡単にするために、新しいNPMスクリプトが追加され、ローカルのDocker環境でComposer がインストールされたバージョンのPHPUnitを使ってテストスイートを実行できるようになりました。
// ローカルのDockerコンテナにインストールされた
// バージョンのPHPUnitを使って実行します。
npm run test:php
// ローカルのDockerコンテナ内で、Composer経由でインストールした
// バージョンのPHPUnitを使用して実行します。
npm run test:php-composer
テストスイートをPHP 8/PHPUnit >= 8と互換性のあるものにするには、こちらを参照してください。
外部ライブラリー
WordPress Core(WP本体)にバンドルされている外部ライブラリがPHP8との互換性に関する問題が修正されました。
(このライブラリの今後のリリースに変更が含まれるように、必要に応じてプルリクエストが作成された。)
SimplePie
SimplePieがバージョン1.5.5から1.5.6にアップデートされました(#51521参照)。
さらに、WP_Feed_Cacheクラスが非推奨になり、SimplePie < 3がプラグイン内でロードされたときだけ、下位互換性のためにロードされるようになりました(#51629および#29204参照)。
sodium_compatが更新され、PHP8で削除された MB_OVERLOAD_STRING 定数にアクセスしようとするとエラーが発生するようになりました (#51399参照)。
Text_Diff が更新され、"Non-static method cannot be called statically"のFatal Errorが修正されました (#51559参照)。
追記事項
そのほか細かいところでの修正がいくつかあります。
PHP8で非推奨、削除されたもの
PHPの関数create_function()の使用を停止しました。この関数はPHP7.2.0で非推奨になり、PHP8で削除されています。(#50899参照)。
PHP8では、libxml_disable_entity_loader()が非推奨になりました。(#50898参照)。
エラー制御演算子 - @
PHP7までは、処理が致命的なエラーでも@でログ出力を抑制していました。これがPHP8では@演算子を使っても出力されます。
本番環境ではこのメッセージが表示されないようにする必要があります。情報漏えいの原因になるから。
アトリビュート追加によるコメント構文の変更
ハッシュコメント演算子#の直後に[]つけるコメントはサポートされなくなりました。この構文はPHP8で追加されたアトリビュートに使用されるようになったから。
PHP RFC
is_gd_image()関数のパラメータとリターン値の変更
PHP8では、リソース関連のPHP拡張パッケージの一部でリソース型変数を使うのを辞め、代わりにクラスオブジェクトを使うように変更されました。
画像を使うGD拡張パッケージも同様です。
そこで、WordPressで使う、is_gd_image()のパラメータとif文の条件にGDのイメージインスタンス、GdImageが追加されています。
WordPress.orgリファレンス
ソート順が変わる可能性
PHP7以前の動作に基づいて特定のソート順に依存するコードがあるとき、失敗する可能性があるらしい。
具体例が出てないんですが、色々なパターンがありすぎて列挙するのことができないのか?
『何かソートがおかしい』というときは条件を見直しましょう。PHP8で変更された関数などを使っているはずです。
PHP関数のパラメータとリターンタイプの変更
様々な PHP 関数のパラメータ/リターンタイプが変更され、影響を受ける可能性があります。微妙な変更点としては、 substr() が常に文字列を返すようになりました。以前は string|false を返していました。
結論。やってみないと分からない。
これだけのボリュームを見てると、かんたんに上手くいきますよとは言えません。
少しずつ環境を作りながらテストする必要があります。
プラグインを一旦、全無効化。
テーマをWP5.6内包のテーマに変更。
PHP8にバージョンアップ。
1回目のテスト。(WPが動くか?)
テーマを自分のものに変更。
2回目のテスト。(テーマが動くか?)
プラグインを1個ずつ有効化してテスト。
3回目以降のテスト。(プラグインが動くか?)
このように自分の環境を小刻みに分割してテストを実行していきます。
WordPress.orgで公開されているサードパーティ製のテーマやプラグインなら、テスト前に対応バージョンを確認しましょう。
WP5.6未満ならやる意味がありません。
それ以外で配布されている完全なサードパーティ製の場合、作成者に問い合わせるしかありません。個人的にはこのパターンが一番やっかい。
対応に消極的な人が多そうだから。
WordPressは比較的かんたんにテーマやプラグインが作れるので、完全なサードパーティ製は有料化してすぐに稼ぎたいという目的の人が多いです。
(WordPressは無料が基本。)
そういうものは、さっと稼いでさっと引くのでこういうときのリスクが高い。気をつけましょう。