はじめに
案件で PHP7.0 → PHP8系(8.0〜8.3) へアップグレードを行いました。
PHP8というと「破壊的変更が多い」という印象が強いですが、
実際に触ってみると “書きやすくなった” と感じるポイントもかなり多い です。
この記事では、PHP8で追加された機能の中から
- 実務で使いやすいもの
- 設計改善につながるもの
を中心にまとめます。
※PHP7系で追加された機能は含めていません。
1. 型システムの進化(かなり強い)
PHP8では型表現が一気に強化されました。
「なんとなく曖昧」だった部分を、明示できるようになっています。
1.1 Union Types(PHP8.0)
function format(int|string $value): string {
return (string)$value;
}
複数の型を許容できるようになりました。
これまではPHPDocで書いていた内容を、
正式な型として宣言できます。
外部APIやDB値を扱う境界層で特に便利です。
1.2 mixed(PHP8.0)
function dumpValue(mixed $value): void {
var_dump($value);
}
「何でも受け取る」ことを明示できる型。
曖昧さを許容しつつ、意図をコードに残せるのがポイントです。
1.3 Intersection Types(PHP8.1)
function process(Iterator&Countable $value) {}
複数の型を同時に満たすことを要求できます。
インターフェース設計がより厳密に書けるようになります。
1.4 never 型(PHP8.1)
function redirect(string $url): never {
header("Location: " . $url);
exit;
}
「この関数は絶対に戻らない」ことを保証できます。
フレームワーク開発や基盤コードで地味に効きます。
1.5 true / false 型(PHP8.2)
function alwaysTrue(): true {
return true;
}
bool よりも厳密な型指定が可能になりました。
ライブラリ実装側で特に意味を持ちます。
2. クラス・オブジェクト周りの進化
2.1 Constructor Property Promotion(PHP8.0)
class User {
public function __construct(
private string $name,
private int $age
) {}
}
プロパティ宣言と代入を同時に書けます。
DTOやValueObjectがかなりスッキリします。
2.2 Named Arguments(PHP8.0)
createUser(name: "Taro", age: 20);
引数の順番を気にせず呼び出せます。
引数が多いメソッドで読みやすさが上がります。
2.3 Attributes(PHP8.0)
#[Route('/users')]
class UserController {}
アノテーション相当の仕組みが言語機能として追加されました。
フレームワークとの相性が良く、
メタデータの標準化が進みました。
2.4 readonly properties(PHP8.1)
class User {
public readonly string $id;
public function __construct(string $id) {
$this->id = $id;
}
}
一度だけ代入可能なプロパティ。
不変オブジェクトを安全に表現できます。
設計の質が上がると感じました。
2.5 readonly class(PHP8.2)
readonly class Config {
public function __construct(
public string $host,
public int $port
) {}
}
クラス全体をreadonlyとして扱えます。
設定値オブジェクトなどに便利です。
2.6 Enums(PHP8.1)
enum Status: string {
case Open = 'open';
case Closed = 'closed';
}
定数の寄せ集めから卒業できます。
型安全 + IDE補完が効くので、
個人的にかなり嬉しい追加でした。
3. 制御構文・書きやすさの改善
3.1 match 式(PHP8.0)
$statusLabel = match ($status) {
1 => 'open',
2 => 'closed',
default => 'unknown',
};
-
===(厳密比較) - 値を返す式
- fall-throughしない
switchよりも安全で読みやすいです。
実務でも積極的に置き換えています。
3.2 Nullsafe operator(PHP8.0)
$name = $user?->profile?->name;
nullチェック地獄から解放されます。
ネストが深いレスポンス処理で特に効果大です。
4. 実行系・標準ライブラリの強化
4.1 JIT(PHP8.0)
Just-In-Timeコンパイルが導入されました。
数値計算などでは効果が出るケースがありますが、
Webアプリでは限定的なことも多い印象です。
4.2 Fibers(PHP8.1)
軽量スレッドのような制御構造。
非同期処理フレームワークの基盤として利用されます。
直接触る機会は少ないですが、重要な進化です。
4.3 Random\Randomizer(PHP8.2)
乱数生成APIが整理され、
より明確で安全な設計になりました。
セキュリティ意識の高い実装ではありがたい変更です。
5. 実務で「使うと効く」おすすめ機能
個人的に特に効果を感じたのはこのあたりです。
- match(分岐の明確化)
- Nullsafe operator(nullチェックの簡略化)
- Union Types / mixed(境界層の型表現)
- Enums(定数だらけの箇所の改善)
- readonly(不変オブジェクトの安全性向上)
まずはこのあたりから取り入れるのがおすすめです。
まとめ
PHP8は「厳格化された怖いバージョン」というよりも、
- 型をしっかり書けるようになった
- コードの意図を明確にできるようになった
- 設計しやすくなった
という進化が大きいと感じました。
アップグレード済みでも、
まだ7系っぽい書き方をしているコードは意外と多いと思います。
少しずつでも8系の機能を取り入れていくと、
コードの見通しがかなり良くなるのでは、と思いました。