【PHP】PHP7.4から8.1にバージョンアップしてみた

## はじめに

プロジェクトのPHPのバージョンを7.4から8.1にバージョンアップする作業を行いました。

今回のバージョンアップ作業で学んだ手順や考慮するべき点についてまとめていきたいと思います。

## この記事でやること

PHP7.4から8.1にバージョンアップする。

## 環境
- EC2を利用しています
    - OSイメージ:Amazon Linux 2 Kernel 5.10
- PHPのバージョン: PHP 7.4.33 (cli)
- PHPUnitのバージョン: 9.5.28
- CakePHPのバージョン: 4.2.12
- nginx: nginx/1.22.0
- php-fpm: PHP 7.4.33 (fpm-fcgi)

## 事前調査・準備

### バージョンアップに関する情報を集める

#### PHP

PHPの各バージョンはリリースから3年間サポートされます(2年間のアクティブサポート＋セキュリティサポート1年)が、PHP7.4はセキュリティサポートが2022年11月28日で終了しているため、今後の保守を考えてPHP8.1へのバージョンアップを実施することになりました。

[PHPのサポート情報](https://www.php.net/supported-versions.php)

まずは公式ドキュメントを参照し、互換性のない変更点を確認します。

[PHP7.4.xからPHP8.0.xへの移行](https://www.php.net/manual/ja/migration80.php)
[PHP8.0.xからPHP8.1.xへの移行](https://www.php.net/manual/ja/migration81.php)

#### PHPUnit

PHPUnitでテスコードを作成していたため、PHPとPHPUnitの対応関係を調べる必要がありました。

現在のPHPUnitのバージョンを確認します。
```
$ ./vendor/bin/phpunit --version

PHPUnit 9.5.28 by Sebastian Bergmann and contributors.
```

[PHPとPHPUnitのバージョン対応一覧表](https://phpunit.de/supported-versions.html)を見るとPHPUnit9系はPHP7.3以上のバージョンに対応していることがわかりました。

現在のPHPUnitのバージョンが9.5.28、アップデート後のPHPのバージョンが8.1なので問題ないことが確認できます。

#### CakePHP

CakePHPとPHPの対応関係を確認します。

現在のPHPUnitのバージョンを調べます。
```
$ cat ./vendor/cakephp/cakephp/VERSION.txt

////////////////////////////////////////////////////////////////////////////////////////////////////
// +--------------------------------------------------------------------------------------------+ //
// CakePHP Version
//
// Holds a static string representing the current version of CakePHP
//
// CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
// Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
//
// Licensed under The MIT License
// Redistributions of files must retain the above copyright notice.
//
// @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
// @link          https://cakephp.org
// @since         CakePHP(tm) v 0.2.9
// @license       https://opensource.org/licenses/mit-license.php MIT License
// +--------------------------------------------------------------------------------------------+ //
////////////////////////////////////////////////////////////////////////////////////////////////////
4.2.12
```

[CakePHP4のシステム要件](https://book.cakephp.org/4/ja/installation.html#id2)によればCakePHP4系はPHP7.4以上(PHP8.1も含む)に対応しているため、こちらも問題ないことがわかりました。

### 検証環境の用意

今回バージョンアップするサービスはすでに展開されていたため、バージョンアップ作業がうまくいくかどうか、バージョンアップ後にサービスが機能するかどうかを事前に別の環境で確かめる必要がありました。

サービスが動いているEC2インスタンスとは別のEC2インスタンスを利用し検証を行い、PHP8.1にバージョンアップ後にテストコードを実行し、挙動に問題が無いことを確認した上で、本番環境でのバージョンアップを行いました。


## PHP8.1へのバージョンアップ手順

PHPに関する設定を記述するphp.iniファイルのバックアップを取ります。

まずphp.iniファイルの場所を探します。
```
$ find / -name "php.ini" -ls

8651969   64 -rw-r--r--   1 root     root        62221  1月 21 03:18 /etc/php.ini
```

/etcディレクトリ配下にあることが分かったので、バックアップを作成します。
```
$ cp -a /etc/php.ini /etc/php.ini.org
```

この際に自分で変更を加えたphp.iniがあるなら合わせてバックアップを取っておきます。

次に現在のPHPのバージョンを確認します。
```
$ php -v

PHP 7.4.33 (cli) (built: Nov 19 2022 00:22:13) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
```

インストール済みのPHPパッケージを確認します。バージョンアップ後にも同じパッケージをインストールするため、出力をメモしておきます。
```
$ yum list installed php*

読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
インストール済みパッケージ
php-cli.x86_64                          7.4.33-1.amzn2                      @amzn2extra-php7.4
php-common.x86_64                       7.4.33-1.amzn2                      @amzn2extra-php7.4
php-fpm.x86_64                          7.4.33-1.amzn2                      @amzn2extra-php7.4
php-intl.x86_64                         7.4.33-1.amzn2                      @amzn2extra-php7.4
php-json.x86_64                         7.4.33-1.amzn2                      @amzn2extra-php7.4
php-mbstring.x86_64                     7.4.33-1.amzn2                      @amzn2extra-php7.4
php-mysqlnd.x86_64                      7.4.33-1.amzn2                      @amzn2extra-php7.4
php-pdo.x86_64                          7.4.33-1.amzn2                      @amzn2extra-php7.4
php-xml.x86_64                          7.4.33-1.amzn2                      @amzn2extra-php7.4
```

現在のPHPを削除するため、ワイルドカードを使ってPHPと名前のついたファイルを削除します。
```
$ yum remove "php*"
```


インストールできるPHPを確認します。

Amazon Linux Extrasを使用することでAmazon EC2での使用に最適化されたパッケージを利用することができます。

php7.4のトピックが有効になっていることがわかりました。
```
$ amazon-linux-extras list available | grep php

42 *php7.4=latest            enabled      [ =stable ]
_  php8.0                   available    [ =stable ]
_  php8.1                   available    [ =stable ]
```

PHP7.4を廃止します。
```
$ amazon-linux-extras disable php7.4
$ amazon-linux-extras list available | grep php

51  php8.0                   available    [ =stable ]
66  php8.1                   available    [ =stable ]
```

8.1のダウンロードします。
```
$ amazon-linux-extras install php8.1
```

インストール済みのパッケージを確認します。
```
$ yum list installed php*

インストール済みパッケージ
php-cli.x86_64                          8.1.14-1.amzn2                      @amzn2extra-php8.1
php-common.x86_64                       8.1.14-1.amzn2                      @amzn2extra-php8.1
php-fpm.x86_64                          8.1.14-1.amzn2                      @amzn2extra-php8.1
php-mysqlnd.x86_64                      8.1.14-1.amzn2                      @amzn2extra-php8.1
php-pdo.x86_64                          8.1.14-1.amzn2                      @amzn2extra-php8.1
```

不足しているパッケージをインストールします。
```
$ yum install php-intl php-json php-mbstring php-xml
```

バージョン確認を確認します。
```
$ php -v

PHP 8.1.14 (cli) (built: Jan 20 2023 18:11:30) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.14, Copyright (c) Zend Technologies
```

nginxとphp-fpmの再起動を行います
```
$ systemctl restart nginx php-fpm
```

これでバージョンアップすることができました！

テストコードの実行・ブラウザからの挙動を確認します。

## まとめ

PHPのバージョンアップに伴いPHPunitやCakePHP等の関連するパッケージやフレームワークとの対応も調査する必要があることを学びました。

また今回はバージョンアップ後の互換性のない変更について、ドキュメントを読むこと・バージョンアップ後にテストコードを実行することで影響範囲を確認しましたが、静的解析ツールを使った調査方法(参考: [PHP8などへ移行する際の互換性チェック](https://www.bit-hive.com/articles/20230126))などもあるようなので、今後バージョンアップ作業を実施するときは使ってみようと思います。

気になる点や感想などあればぜひ教えて下さい。


## 参考
- PHP8.1へのバージョンアップ手順
    - [Amazon Linux 2 に関するよくある質問](https://aws.amazon.com/jp/amazon-linux-2/faqs/)
    - [Amazon Linux でのPHPバージョンアップ](https://qiita.com/hot-and-cool/items/d445e831995d82dfe4ab)