本文へスキップ
BecomeCoder

PHPコース · 第8章 モダンPHPと道具 · レッスン28

PHP8の新機能 ― enum・名前付き引数・コンストラクタプロモーション

ブラウザで完結

導入

PHP 8 系では、コードをより短く安全に書ける新機能がいくつも加わりました。すでに match(レッスン8)や型宣言(レッスン15)で触れましたが、ここでは実務でよく使う3つ――enum(列挙型)名前付き引数コンストラクタプロモーションを紹介します。

説明

enum(イーナム/列挙型) は、「決まった選択肢のどれか」という値を表す専用の型です。"pending" のような文字列を直接あちこちに書くと、タイプミスに気づけません。enumにしておけば、PHP がその範囲の値しか許さないよう守ってくれます。

<?php
enum Status: string {
    case Pending = "pending";
    case Approved = "approved";
    case Rejected = "rejected";

    public function label(): string {
        return match ($this) {
            Status::Pending => "審査中",
            Status::Approved => "承認済み",
            Status::Rejected => "却下",
        };
    }
}

$s = Status::Approved;
echo $s->value, "\n";     // approved
echo $s->label(), "\n";   // 承認済み

enum Status: string のように型を付けたものをバックド enumと呼び、->value で実際の値(この例では "pending" など)を取り出せます。enumにもメソッドを定義でき、match ($this) で「自分がどのケースか」に応じた処理を書けます(match はレッスン8で学んだものと同じです)。

名前付き引数 は、関数を呼び出すときに 引数名: 値 の形で値を渡す書き方です。引数の順番を覚えていなくても、意図がひと目でわかる形で渡せます。

<?php
function makeUser(string $name, int $age = 20, string $role = "member"): string {
    return "{$name}({$age}歳・{$role})";
}

echo makeUser("田中"), "\n";                        // 田中(20歳・member)
echo makeUser(name: "鈴木", role: "admin"), "\n";    // 鈴木(20歳・admin):$age は省略してデフォルト値のまま

途中の引数を飛ばして、必要な引数だけを名前で指定できるのが名前付き引数の強みです。特に、引数が多い関数やデフォルト値の多い関数で読みやすくなります。

コンストラクタプロモーション は、コンストラクタの引数にそのまま可視性(public など)を書くことで、「引数の受け取り」と「プロパティへの代入」を1行にまとめる書き方です。レッスン21で書いた __construct() を短くできます。

<?php
class Point {
    public function __construct(
        public float $x,
        public float $y,
    ) {}

    public function toString(): string {
        return "({$this->x}, {$this->y})";
    }
}

$p = new Point(x: 3, y: 4);
echo $p->toString(), "\n";   // (3, 4)

public function __construct(public float $x, public float $y) {} は、レッスン21のように public float $x;$this->x = $x; を別々に書くのと同じ意味になります。ボイラープレート(毎回同じ形で書く決まり文句のコード)を減らせるため、実務のクラスでとてもよく使われる書き方です。

やってみよう

Status enum に case Draft = "draft"; を追加し、label()match にも枝を足してみましょう。Point クラスに z 座標を追加して3次元にしてみるのもよい練習です。

演習

コンストラクタプロモーションを使って、public float $widthpublic float $height を持つクラス Rectangle を作ってください。面積を返すメソッド area(): float$this->width * $this->height を返す)も用意します。new Rectangle(width: 4, height: 5) のように名前付き引数でインスタンス化し、area() の結果を表示してください。

ヒント1を見る

class Rectangle { public function __construct(public float $width, public float $height) {} public function area(): float { return $this->width * $this->height; } }

ヒント2を見る

$r = new Rectangle(width: 4, height: 5); echo $r->area(), "\n";

実際に動かしてみよう

下のエディタにPHPを書いて「実行」を押すと、ブラウザ内で動く本物のPHP(php-wasm)で出力が表示されます。コードは必ず <?php で書き始めます。本文の例をそのまま試したり、書き換えたりしてみましょう(初回だけPHPの読み込みに少し時間がかかります)。

PHP — ブラウザ内で実行

ブラウザ内で動く本物のPHP(php-wasm / PHP 8.4)を読み込みます(初回のみ読み込みに少し時間がかかります)。
スクロールして表示された時点でも自動で読み込まれます。