まず結論:いきなり本番で上げない
PHP 8.0 では言語の挙動そのものがいくつか変わっており、7.x で動いていたコードがエラーで止まったり、エラーを出さずに違う動きをしたりします。 本番で PHP のバージョンを切り替える前に、必ず次の順で進めてください。
- バックアップ(スナップショット)を取る — 元に戻せる状態を先につくる
- 検証環境をつくる — 本番と同じ OS・同じコード・同じデータ(DB のコピー)で
- 静的解析で先に洗い出す — コードを動かさずに、非互換の箇所を一覧にする
- 検証環境で PHP を上げ、エラーログを見ながら直す
- 主要な画面と機能を一通り確認する — ログイン、問い合わせフォーム、決済、管理画面など
- 本番に反映し、しばらくログを監視する
静的解析で先に洗い出す
コードを実行せずに、非互換の書き方を機械的に探せます。代表的なのは次の 2 つです。
# PHPCompatibility: 指定バージョンで問題になる書き方を一覧にする
composer require --dev phpcompatibility/php-compatibility
vendor/bin/phpcs -p --standard=PHPCompatibility --runtime-set testVersion 8.3 src/
# Rector: 一部は自動で書き換えられる(必ず差分を確認してから取り込む)
composer require --dev rector/rector
vendor/bin/rector process src --dry-run
出てきた件数を見ると、移行がどのくらい重い作業になるかのおおよその目安になります。
詰まりやすい点と直し方
1. 文字列と数値の比較の結果が変わった(8.0)
PHP 7.x では 0 == "abc" が true でしたが、8.0 以降は false です。
エラーにならず、条件分岐の結果だけが静かに変わるため、最も気づきにくい変更です。
入力値のチェックやログイン判定などで == を使っている箇所は、===(型まで比較)に直すか、比較する前に型をそろえます。
2. 削除された関数を使っている
| 使えなくなったもの | 削除・非推奨 | 置き換え先 |
|---|---|---|
mysql_* 系の関数 | 7.0 で削除 | mysqli または PDO |
ereg / split など | 7.0 で削除 | preg_match / preg_split |
each() | 8.0 で削除 | foreach |
create_function() | 8.0 で削除 | 無名関数 function () { ... } |
utf8_encode() / utf8_decode() | 8.2 で非推奨 | mb_convert_encoding() |
PHP 5.x から一気に上げる場合は、mysql_* 系の置き換えが作業の大半を占めることがよくあります。
3. 内部関数に null を渡すと警告が出る(8.1)
strlen(null) や htmlspecialchars(null) のように、文字列を受け取る関数に null を渡すと非推奨の警告(Deprecated)が出るようになりました。
データベースの空欄(NULL)をそのまま画面に出しているコードで大量に発生し、ログが埋まって本当のエラーが見えなくなります。
htmlspecialchars($value ?? '') のように、渡す前に空文字へ置き換えます。
4. 宣言していないプロパティへの代入(8.2)
クラスで宣言していないプロパティに $this->foo = ... と代入すると、非推奨の警告が出るようになりました。古いフレームワークで作られたシステムに多い書き方です。
本来はクラスにプロパティを宣言して直します。急ぐ場合は、クラスに #[\AllowDynamicProperties] を付けて一時的に警告を止める方法もあります。
5. 必須の引数より前に、省略できる引数がある
function f($a = null, $b) のような定義は、8.0 から非推奨になりました。
省略できる引数は後ろへ移すか、既定値を外して呼び出し側を直します。
6. フレームワーク自体が PHP 8 に対応していない
CakePHP 2 系、Laravel 5 系、CodeIgniter 2・3 系などの古いフレームワークは、フレームワーク本体が PHP 8 に対応していないことがあります。 小さな更新で済むのか、大きく作り直す必要があるのかで作業量が桁違いに変わるため、最初に見極めます。
7. 使っている部品(Composer のパッケージ)が対応していない
composer.lock で固定されている古いパッケージが、新しい PHP に対応していないことがあります。
composer why-not php 8.3 を実行すると、どの部品が移行を妨げているかを一覧にできます。
8. 拡張モジュールの入れ忘れ
サーバーに新しい PHP を入れるとき、mbstring・gd・intl・zip・xml などの拡張モジュールは自動では入りません。
入れ忘れると、画面が真っ白になる、画像のアップロードだけ失敗する、といった症状になります。
元のサーバーで php -m を実行して一覧を控え、新しい環境と見比べます。
9. php.ini の設定が初期値に戻る
新しいバージョンの PHP は、設定ファイル(php.ini)も別になります。
アップロードできるファイルの大きさ(upload_max_filesize)、使えるメモリ(memory_limit)、タイムゾーン、short_open_tag などを元の設定に合わせ直さないと、以前は動いていた機能が止まります。
作業量の目安を左右するもの
- 元のバージョン: 7.4 からなら比較的軽く、5.x からだと書き換えが大きくなります
- フレームワーク: 本体が PHP 8 対応版に上げられるかどうか
- 静的解析で出た件数: 何十件か、何千件か
- 検証環境をつくれるか: 本番しかない環境では、まず検証環境づくりから始まります
- 資料の有無: 作った人と連絡が取れるか、仕様がわかる資料があるか
無料診断では、これらを確認したうえで「パッチで済むか、移行が必要か、どのくらいの重さか」をお伝えしています。
古い PHP で動いているサイト・システムの移行を引き受けています。
まず無料で、移行が必要か・どのくらいの重さかを判定します。