WordPressサイト、プラグイン、テーマを鑑みたPHPのバージョンアップは、終わりのない作業です。定期的に繰り返していく必要があります。この作業を効率的に行うにはどうしたらいいのでしょうか。見落としがないようにするにはどうしたらいいのでしょう。おすすめのプロセスとは。

今回の記事では、これらの疑問(とそれ以上)に答えながら、ロードマップを含め、WordPressサイト、プラグイン、またはテーマのPHP 8.xへのスムーズな移行に必要な要素を見ていきます。

今回は、PHPのエキスパートであるJuliette Reinders Folmer氏へのインタビューに基づき、その内容をご紹介します。彼女は日常生活のほとんどをプログラミングとその関連分野に捧げ、主にWordPressを含むオープンソースプロジェクトを中心に活動しています。

それではスムーズな移行を目指して準備を始めましょう。必要なステップを詳しくご紹介します。

PHP 8.xの変更点

まずは予備知識として、変更点の概要について以下の各種ページをお勧めします。

これらの記事に目を通すことで、PHP 8.xで何が変わったのか、PHPプロジェクトを問題なく稼働させるために何をすべきなのか、全体像が見えるはずです。

「何から始めればいいのか」わからない場合でも問題ありません。Juliette氏との会話の中で、これについて詳しく議論を繰り広げました。この記事では、PHP 8.xに切り替える方法について、できる限り包括的に説明をしたいと思います。

また、MyKinsta(WordPressサイト、アプリケーション、データベースのすべてを管理するKinsta独自のコントロールパネル)でのさまざまな操作方法についても随時扱うことにします。

PHP8.xへの切り替え

PHP 8.xへの切り替えは一見簡単そうに思えるかもしれません。技術的にはその通りです。多くのホストで、管理パネルにあるPHPバージョンの変更ボタンを押すだけで完了します。Kinstaでは、PHPバージョンの切り替えは、MyKinstaでワンクリックだけで行うことができます。

しかし、その前に確認しておかなければならないことがあります。知識・経験のレベルに応じて、以下をお勧めします。

  • PHPの知識があまりないまま、標準的なテーマとプラグインを使って自分のWordPressサイトを構築した場合には、開発者や代行業者に依頼し、自分のサイトがPHP 8.xで動作するのに適した状態であるか確認してもらってください。おすすめの事業者はパートナーページをご覧ください。
  • WordPressサイトが外部の開発会社や代行業者によって構築されたものであれば、その会社に連絡して、PHP 8.xで実行できるかどうか尋ねてください。
  • 自身でWordPressサイトを構築した場合、例えば、独自のテーマや独自に開発したプラグインを使用した場合には、以下のロードマップを参照してください。

もし、あなたのサイトが最初の2つのカテゴリー(最初の2つのいずれか)に分類されるなら、この記事の続きを読み理解を深めることは大歓迎ですが、PHP 8との互換性を自力でテストすることはお勧めしません。プロに任せるのが得策です。

また、どのような選択をするにしても、本番サイトをいきなりPHP 8に切り替えて「機能するか」どうか確認するのはお勧めしません。自分のサイトがPHP 8で動作するのを見るのが待ちきれないのであれば、ステージング環境でのテストから始めましょう。優れたサーバー/ホスティングサービスであれば、ステージング環境を簡単にセットアップすることができるはずです。

MyKinsta─環境を新規作成する
MyKinsta─環境を新規作成する

ステージング環境では、PHP 8.xを有効にして、サイトでうまく機能するかどうかを確認できます。また、サイトのローカルコピーで作業することも可能です。無料の開発ツールDevKinstaを使えば、MyKinstaから簡単にサイトをインポートし、その後、PHPバージョンを8.0または8.1に変更することができます。

ステージング環境で問題が見られない場合でも、実際に問題がないとは限りません。その理由は、以下のロードマップをご覧ください。

PHP 8.x互換性テストの枠組み

優れたソフトウェアに欠かせない合い言葉、それがテストです。WordPressサイト、テーマ、プラグイン、WordPressコアなどのコンポーネントに無くてはならない概念であり、これを徹底することで、予期せぬ事態の発生を未然に防ぐことができます。

ソフトウェア開発プロジェクトは、その大部分がテストによって構成されています。それでは、PHP 8.xへの移行をスムーズに行うためのテストについて見ていきましょう。DevOpsツールについては、ツールをまとめたこちらの記事をご覧ください。

具体的には、以下の種類のテストを扱います。

それでは、テストの種類を詳しく見ていきましょう。

静的解析(静的テスト)

PHP開発者としての最初のステップは、さまざまなツールを使ってコードの静的解析を行うことです。静的解析とは、コードを実行することなくソフトウェアを分析するプロセスです。静的解析を行うことで、エラーの検出、PHP 8.xとの互換性の問題の検出、コーディング標準(例えば、WordPress Coding Standards)の実施、さらにはコードの修正とクリーンアップが可能となります。

静的解析に便利なツール

静的解析は、以下のような様々なツールで行うことができます。

この記事を書いている時点では、PHPCompatibilityの最新リリースで、すべてのPHP 8.1のチェックがサポートされているわけではありません。PHP 8.1のチェックは開発版リリースで扱われているので、 PHPCompatibilityを使ってプロジェクトを解析し、どんなエラーや推奨事項があるかを確認する際には、 (今のところ)そちらを使うようにしてください。

PHP 8.1のチェックは、まもなく新しい「メジャー」バージョンでリリースされる予定です。この最新情報を知りたい、GitHubアカウントをお持ちの方は、PHPCompatibilityのGitHubリポジトリを開き、「Watch」>「Custom」>「Releases」に移動し、新しいバージョンがリリースされたときに通知を受け取ることを選択することができます。

PHPの特定のバージョン(またはバージョンの範囲)に対する互換性のみをテストするPHPCompatibilityは、簡単にセットアップできます。PHPCompatibility内でtestVersion(例えば8.0+(8.0以上))を実行すると、最良の結果を得ることができます。

非推奨または削除された関数、関数パラメータのデフォルト値の変更、括弧なしのconcatの使用、関数名としてmatchを使用するかどうか(PHP 8.0から予約語であるため)などに気をつける必要があります。

PHPCompatibilityのGitHubページのスクリーンショット
PHPCompatibilityのGitHubページのスクリーンショット

PsalmとPHPStanは優れた追加の機能で、変数型に関連するさらなるチェックを行うができます。これらのツールの欠点は、PHP 8.0と8.1に関するレポートの取得に多くの設定が必要なことです。たとえ成功したとしても、多くのフォルスポジティブ(誤検出)が予想されます。これはつまり、静的解析の限界によって、間違って問題が検知される可能性があるということです。

この2つのツールの結果を正しく解釈するには、確かな知識が必要ですが、それがあれば、PHPCompatibilityでは見つけられない、さらなる非互換性を特定することができます。PsalmPHPStanについては、それぞれのリンク先のドキュメントをご覧ください。

ここまでのまとめ

  • PHPCompatibility、Psalm、PHPStanを使って静的解析を行う
  • 誤検知ではない全ての問題の解決にあたる
MyKinstaでログファイルを表示する
MyKinstaでログファイルを表示する

単体テスト

次のステップでは、単体テストを行います。単体テストとは、コードの断片を個別にテストするテスト手法です。単体テストでは、各ユニットに対して特定のターゲットとなるテストを開発します。これには、複数のシナリオを想定することも必要になります。できれば、各シナリオを他のシナリオとは別にテストし、テストが互いに独立するようにしたいところです。

もちろん、単体テストがあるだけでは十分ではありません。単体テストを実行する必要があります。単体テストは、JenkinsGitHub ActionsTravisなどのCI(継続的インテグレーション)ツールを使って自動化するのが最適です。

GitHub Actionsの例
GitHub Actionsの例

複数のバージョンのPHPをサポートする

プラグインビルダーとして、複数のPHP バージョンをサポートしたい場合は、CIでテストを実行する際に、サポートするすべてのPHPバージョンを網羅するようにしましょう。

もちろん、新しいバージョンのみをサポートすることもできます。この選択はあなた次第です。

複数のバージョンのPHPでテストを行うには、PHPのバージョンに応じて複数のPHPUnitを使用する必要があります。PHPUnitは数年前からテストの書き方に影響を与えるような変更を加えているので、この作業は複雑になるかもしれません。

これを回避するには、PHPUnit Polyfills(Juliette氏による開発、Yoastによるスポンサー)を使用することができます。これを使うと、公式にはPHPUnit 9をサポートしていない(つまり、PHP 8.xで実行できる)テストを書くことができます。このポリフィルを使うと、PHPUnit 4.x から 9.x まで、そしてPHP 5.4から PHP 8.1までのテストが動く(現在のところ)ようになります。[/notice]

これでテストが実行できるようになったので、次はテストで見つかった問題を修正します。

コードカバレッジ

ここでご紹介してきたテストを実行することで、バージョン間の非互換性を高い精度で発見することができます。

とは言え、その際には、テストのコードカバレッジに注意してください。

  • 例えば、関数Aがあって、それに対するテストを書き、関数Aは関数内のロジックの一部として関数B、C、Dを呼び出すとします。
  • 関数Aのテストは、関数Aのロジックをテストするために書かれていますが、テスト中に関数B、C、Dも呼び出すことになります。関数B、C、Dについては、通常は「ハッピーパス」(すべてがうまくいく状況)のみをテストするため、完全にテストすることにはなりませんが、そのようなコード(の一部)は、関数Aのテスト中に実行されます。
  • 各テストについて、具体的にどのコードがテストされているのかを示すことが重要です。そのためには、各テストに「@covers」をつけます。こうすることで、B、C、Dはコードカバレッジの計算に「カウント」されず、コードのどの部分がテストによって網羅されているかを確認できます。

開発者はしばしば、(時に無意識のうちに)「ハッピーパス」を目指してテストを書くものです。そのようなケースでは、予期せぬデータが関数に渡されたときに何が起こるかをテストすることも必要です。期待される値や型だけを使ったテストでは不十分ということです。

上の引用文にある2つ目の部位は往々にして忘れられがちですが、おそらく最初の部位よりももっと重要です。不正な型を渡すとどうなるのでしょうか?エラーメッセージが表示されるでしょうか?それとも、その変数がキャストされ、関数が通常通り実行されるでしょうか?予期せぬ値が関数に渡された場合はどうなるでしょうか?

予期せぬ変数、型、値で関数をテストするようにしてください。そうして初めて、新しいPHPのバージョンが引き起こすかもしれない問題を見つけることができます。

PHPはより厳格に

PHPは、PHP自身の関数や動的プロパティのようなものの「型」の扱い方について、 より正確(厳密)になってきています。この変更は、一般に、開発者がエラーのないコード(より少ないコード)を記述できるようになることを目的としています。しかし、これは、PHPの「古い」しきたりに基づいて書かれた既存のコードにとっては、かなり高いハードルになる可能性があります。

PHPのエラーメッセージをより有用なものにするために、既存のコードを新しいPHPのバージョンに対応させるには、より多くの時間がかかることがお分かりいただけたと思います。PHP 5.6で動作するコードをPHP 7.0に対応させるのは、PHP 8.1に対応させるためにコードを改善するのと比べて、ほとんどの場合、ほんのわずかの時間しかかかりません。PHP 7.0は「メジャー」リリースであり、PHP 8.1は「マイナー」リリースであるという事実にもかかわらず、このような状況になっています。

多くの場合、テストは、新しいバージョンをサポートするために何を修正する必要があるかを決定する唯一の信頼できる方法であることに変わりはありません。

単体テストは、以下のようなさまざまなツールで実行できます。

これらのツールの多くは、PHPUnitをベースに、あるいはPHPUnitと連携し構築されています。

結局のところ、どのツールを使うかは重要ではありません。最も重要なことは、テストを行い、新しい PHPのバージョンでテストを実行することです。この作業を助けるものとして、前述のようにPHPUnit Polyfillsのようなツールもあります。

統合テスト

統合テストは、静的解析と単体テストの次に実施するステップです。統合テストでは、実際の状況を”コードユニット”だけでなく、より大きな文脈でテストすることになります。2つの例を挙げると、アクティブな(テスト用の)データベースを使ったテストや、外部APIを使ったテストなどがこれに当たります。

つまり、WordPressのコンテキストでプラグインやテーマのコードをテストし、実際のバージョンを使用する場合、それは定義上、統合テストとなります。

統合テストに使える優れたツールとして、WP Test Utils(これもJuliette氏が書いたもので、Yoastがスポンサーになっています)があります。WP Test Utilsは、統合テストと単体テストの記述を支援するものです。このテストでは、BrainmonkeyMockeryを使ってWordPressを「モックアップ」し、よく使われるWordPressの機能を真似て、WordPressコードではなく、自身のコードをテストすることができます。

WP Test Utilities(GitHub)
WP Test Utilities(GitHub)

WordPressの統合テストは、WordPressとWordPressテストスイートとの統合に関わるため、少々厄介な話になります。プラグインやテーマがどのバージョンのWordPressをサポートしているかによって、異なるPHPバージョンでテストを実行するために、WordPress自体がどのPHPUnitバージョンをサポートしているかを考慮する必要があります。

例えば、WordPress 5.6から5.8では、PHP 5.6からPHP 8.0のテストにPHPUnit 5から7を使用していますが、WordPress 5.9では、WordPressそのものがPHPUnit Polyfillsを使用して幅広いサポートを提供しています。WP Test Utilsは、この違いを克服するための橋渡しとして機能します。

WordPress 5.9以降など、複数のバージョンのWordPressに対して統合テストを実行する方法について、詳しい情報をお求めであれば、WordPress公式サイトのこちらの説明をご覧ください。

手動テスト

単体テストと統合テストが終わり、見つかった問題をすべて解決したら、次は手動テストです。サイトが稼働しており、あなた自身のコードも機能しています。そこでは、プラグインA、B、Cが使用されているとしましょう。これらのプラグインに互換性があるかどうか把握できていますか?

例えば、プラグインの作者に尋ねる(またはそのサイトを見る)などして、PHP 8.xと互換性があるかどうかを確認します。もちろん、問題は、そのプラグインがどのようにテストされたかということです。多くの場合、その答えは「単独でテスト済み」です。プラグインの機能は、通常、他のプラグインを使用せず、WordPress単体でテストされます。また、たとえ他のプラグインがテストに使用されたとしても、あなたが実際に使用しているすべてのプラグインがテストで使用されたとは限らないので、このような互換性の声明は文字通りに受けとらない方がいいでしょう。

例えば、3つのプラグイン(A、B、C)を持つWordPressサイトがあるとします。プラグインBがフィルタを介して不正な変数型を返し、同じフィルタを使用するプラグインCがそれを処理しようとすることがあり得ます。この場合、型が期待されたものでなくなるため、致命的なエラーが発生する可能性があります。この場合、プラグインCは(プラグインBが真犯人であるにもかかわらず)エラーメッセージの犯人であるとみなされます。

プラグインの相互運用性/非互換性は、単独でテストしても発見することは不可能です。アクティブなプラグインが多ければ多いほど、何か問題が発生する可能性は高くなります。例えば、本番サイトからステージング環境(エラーログを有効にした状態)にページリクエストを渡して、実際に何が間違っているのかを発見することは非常に有益です。

この種の問題では、通常、最後に実行されたコード(この場合はプラグインC)にエラーがあったというメッセージが表示されるだけで、プラグインCが問題の原因であるとは限りません。

ほとんどの場合、このような問題を検出し解決するには多くの作業が必要であり、それなりの量の作業が必要になります。エンドツーエンドテストで自動化することは「可能」ですが、WordPressではあまり見かけません。

利用されているプラグインの可用性テスト

開発者や開発チームへのメッセージです。テストが利用可能な場合にのみ、それを受け入れるようにしましょう。こうすることで、手動でのテストが少なくなり、多くの時間を節約することができます。

商用プラグインやテーマを購入する場合は、そのテスト戦略を疑ってみてください。そうすることで、WordPressコミュニティの開発者/開発チームの間で、テストをより重要な議題とする意識が生まれ、私たち全員がそこからメリットを享受することができます。

テストは面倒かつコストがかかるものとみなされがちですが、実際にはお金を節約することにつながります。テストを書く時間の投資は、バグレポートを大幅に減らし、バグ解決に費やす時間を減らすという形で報われるものです。さらに、ソフトウェアの自動化テストでは、既存の機能が引き続き動作することをテストによって素早く確認し、拡張や修正をスムーズに行うことができます。

WordPressホストの役割とPHP 8.x

一般的に、サイト所有者にとって、ホスト/サーバーからの情報提供は望ましいものです。次のような説明がないかどうか確認してみてください。

  • WordPressコア、プラグイン、テーマが(場合によっては)PHPのクロスバージョンと互換性がないことを説明する文書や情報
  • テスト用のオプション(ステージング環境など)
  • エラーの報告場所やサポートへの連絡方法

サイトの所有者は、問題が発生したときにホストに助けを求めることが多いため、これはウェブホストにもメリットとなります。PHP 8.0、8.1、8.2 への切り替えの場合、潜在的な問題について責任を負うのはサイト所有者であり、所有者が切り替えの準備を適切に行うための情報が多いに越したことはありません。

ウェブホストの立場としては、PHP 8.1や8.2を利用可能にすることができますが、その際、問題が表面化する可能性があることを顧客に認識してもらうために、ある程度の意識付けを行う必要があります。本番とは異なるバージョンのステージング環境でサイトをテストすることが推奨されます(KinstaではPHPのバージョンをデフォルトで選択/変更可能です)。

WordPressに最低限必要なPHPバージョン

現在、全ウェブサイトの15%以上がPHPバージョン7.0以下を使っています。これは、公式のWordPressの統計で見ることができます。全WordPressサイトの約83%がPHPバージョン7.4以下を使用しています。バージョン8.0以下は、現在PHPのサポートが終了していることに注意してください。サポートの終了したPHPバージョンを使用すると、セキュリティアップデートがリリースされなくなるため、問題が発生する可能性があります。

この問題を回避するために、WordPressサイトの所有者は、自分のサイトを安全に動作させることができる最低限のPHPバージョンを理解し、常に最新の情報を収集することが重要です。PHPのバージョンを自分で変更したり(Kinstaではすべてのプランで可)、ホストに依頼してサイトを新しいPHPバージョンに更新してもらったりすることができます。極端な場合、新しいバージョンをサポートするサーバー/ホストに切り替えることも可能です。

WordPressは最低でもPHP 7.4があれば機能するため、多くのホストやウェブサイト所有者にとって、サイトを更新する動機は不十分かもしれません。PHP 7.4が2022年11月にセキュリティサポートを迎えているにもかかわらず、このような状況になっています。

WordPressがPHPに最低限求められるバージョンを引き上げることがあれば、多くのサイトでのWordPress更新が余儀なくされるかもしれません。とは言え、特定の古いバージョンに対して、今後も引き続き、セキュリティアップデートがリリースされ続けるでしょう。

まとめ

ウェブサイトをPHP 8.0以上に切り替えるには、いくつかの手順を実行する必要があります。重要な点は以下の通りです。

  • 静的解析
  • 単体テスト
  • 統合テスト
  • 手動テスト

PHP 8.xに移行する際には、「すべて」のテストを適切に行うようにしましょう。サイトが新しいPHPバージョンで正しく、速く、安全に動作するために欠かせないポイントです。

最後に、この記事にご協力いただいたJuliette氏と、記事内で紹介したツールの背後にある彼女の尽力に対して感謝の意を述べたいと思います。

同氏の写真は、Jip Moorsが撮影し、許可を得た上で使用しています。

Marcel Bootsman Kinsta

Kinstaのオランダ市場マーケティングマネージャー。Xアカウントはこちら。