PHP 8 新機能解説:ユニオン型・名前付き引数・Match 式から JIT まで
「PHP 7.4 で十分」と感じていた筆者ですが、実務で PHP 8 を採用したところ、型安全性と DX(開発者体験)が大幅にアップし、コードレビューの指摘も激減しました。
この記事では ユニオン型・名前付き引数・Match 式・JIT を軸に、従来版との違いと導入時の注意点をまとめます。初めて PHP 8 に触れる方も、すでに移行を検討中の方も、読み終えた頃には「使いどころ」がクリアになるはずです。
PHP 8 の進化ポイント早わかり比較
PHP 8 の目玉は「型安全化」と「パフォーマンス向上」です。下表は主要機能を PHP 7.4 と対比したものです。
機能 | PHP 7.4 | PHP 8.0+ |
---|---|---|
ユニオン型 | PHPDoc で擬似指定 | 言語ネイティブで検証 |
名前付き引数 | 未対応 | 順序フリーで呼び出し |
Match 式 | switch 文のみ | 値を返す式で厳密比較 |
JIT | なし | 数値演算特化で高速化 |
ユニオン型:複数型を安全に受け付ける宣言方法
ユニオン型は「int または float」のように複数型を直接シグネチャに書ける仕組みです。IDE の補完が的確になり、実行前に型ミスを捕捉できます。
function add(int|float $a, int|float $b): float {
return $a + $b;
}
戻り値に int|float
を指定することも構文上は可能ですが、数値演算の結果は自動的に float にキャストされるケースが多く、型が曖昧になることもあるため、実務では float
に固定しておくほうが明快です。
DTO とスカラーを混在させる場面では、nullable との組み合わせでテスト量を削減できます。
ユニオン型と null 合体演算子の組み合わせ
たとえば API レスポンスが数値または null を返すケースでは int|float|null
と宣言し、受け取り側で ??
(null 合体)演算子を使うと意図を明確に示せます。これにより暗黙のキャストミスを防ぎつつ、処理の意図がひと目で分かるようになります。
名前付き引数:長大な関数呼び出しと決別
デフォルト値が多いメソッドを呼び出すとき、順序を覚えるストレスから解放されます。
$img = imagecrop(
gd: $src,
width: 200,
height: 200,
x: 100,
y: 50
);
将来の引数追加時も既存呼び出しを壊さずに済むため、ライブラリ設計者・利用者双方の保守コストが下がります。
Match 式:switch と if を置き換える“安全な式”
Match 式は「厳密比較」と「値を返す」という二大特徴を持ちます。これは switch
のような文(statement)ではなく、値を返す“式(expression)”であることが最大の違いです。
フォールスルーが起きず、返り値を変数に直接代入できるため、意図しない fall-through や三項演算子のネスト地獄を防止できます。
$planLabel = match(true) {
$age < 18 => 'Student',
$age >= 18 && $age < 65 => 'Standard',
default => 'Senior',
};
本来、Match 式は「ある値に対して条件ごとに分岐する」構文ですが、上記のように match(true)
を使えば if-elseif
連鎖の代替にもなり、実務では広く用いられています。
三項演算子の単純な置き換えではなく、「条件分岐+値生成」を一行で表現できる点が強みです。
JIT コンパイラ:効果とリスクを正しく見極める
JIT はホットパスをネイティブコード化して実行速度を底上げします。
ただし恩恵が大きいのは Mandelbrot 生成などの 数値演算中心タスク で、Laravel や WordPress の典型的な I/O 多めリクエストでは差が誤差レベル、むしろメモリ使用量増加で不利になるケースも報告されています。
実運用では「バッチ処理だけ JIT 有効、Web フロントは無効」といった構成が現実的です。設定ファイル例は次のとおりです。
; php.ini
opcache.enable=1
opcache.jit=tracing
opcache.jit_buffer_size=64M
本番適用時は APM(Application Performance Monitoring)ツール(例:New Relic、Blackfire、Datadog など)で CPU 使用率とレスポンスタイムを計測し、効果が薄い場合は潔くオフにする判断が重要です。
PHP 7 から 8 への安全なアップグレード手順
まず php -d zend.assertions=1 -d assert.exception=1
でデプリケーション警告を洗い出し、each()
や create_function()
を含む古い構文を排除します。
次に composer why-not php ^8.0
で非対応パッケージを確認し、一時的に互換フォークへ差し替えましょう。
ステージング環境で OPCache と JIT の有効・無効を切り替え、APM でメモリとレスポンスタイムの推移を比較したら、カナリアリリースで流量を段階的に移行します。
最後に本番全台を切り替え、エラー監視を 1 週間ほど強化すれば移行完了です。
まとめ:PHP 8 を導入する前に押さえておきたいポイント
PHP 8 ではユニオン型や名前付き引数で型安全性と記述性が向上し、Match 式で条件分岐が読みやすくなりました。
JIT は数値演算タスクに限定して効果を発揮するため、Web アプリでは基本オフにし、バッチのみオンにする運用が現実的です。
移行前には composer 依存関係を洗い出し、ステージングで OPCache と JIT の有効・無効を APM で比較してください。これらの準備を済ませれば、DX の向上と部分的な高速化を安全に享受できます。