Menu
Coddy logo textTech

Constructor Promotion (8.0)

CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 42/91。

PHP 8.0 では、クラスを定義する際のボイラープレートコードを劇的に削減する機能であるコンストラクタのプロモーション (constructor promotion) が導入されました。プロパティを個別に宣言してからコンストラクタ内で代入する代わりに、これら両方を 1 つのステップで行うことができます。

これまで使われてきた伝統的なアプローチは以下の通りです:

<?php
class Product {
    private string $name;
    private float $price;
    
    public function __construct(string $name, float $price) {
        $this->name = $name;
        $this->price = $price;
    }
    
    public function getInfo(): string {
        return $this->name . ": $" . $this->price;
    }
}

コンストラクタのプロパティ昇格(constructor promotion)を使用すると、アクセス修飾子をコンストラクタの引数に直接追加できます。

<?php
class Product {
    public function __construct(
        private string $name,
        private float $price
    ) {}
    
    public function getInfo(): string {
        return $this->name . ": $" . $this->price;
    }
}

$product = new Product("Laptop", 999.99);
echo $product->getInfo();

出力:

Laptop: $999.99

コンストラクタの引数の前に privateprotected、または public を追加することで、PHP は自動的にプロパティを作成し、値を代入します。同じコンストラクタ内で、プロパティ昇格された引数と通常の引数を混在させることができ、必要に応じてコンストラクタのボディ内にロジックを追加することも可能です。

重要なポイント: コンストラクタのプロパティ昇格(Constructor promotion)は、繰り返しのプロパティ宣言と代入を排除し、完全なカプセル化の制御を維持しながら、クラスをよりクリーンで読みやすくします。

challenge icon

チャレンジ

簡単

コンストラクタのプロモーション(Constructor Promotion)の優雅さを示す連絡先管理システムを構築しましょう。ボイラープレートコードを排除しつつ、適切なカプセル化を維持した、クリーンでモダンなPHPクラスを作成します。

コードは2つのファイルに分けて構成します:

  • Contact.php — コンストラクタのプロモーションを使用して、すべてのプロパティをコンストラクタのシグネチャ内で直接定義する Contact クラスを作成します。連絡先には以下のプロパティを持たせてください:
    • private な $name プロパティ(string)
    • private な $email プロパティ(string)
    • private な $phone プロパティ(string)。デフォルト値は "Not provided" とします。
    コンストラクタのプロモーション構文を使用してください。個別のプロパティ宣言は不要です! "[name] | [email] | [phone]" を返す public メソッド getFullDetails() を追加してください。また、"Contact: [name]" を返すメソッド getSummary() も追加してください。
  • main.php — Contactファイルをインクルードします。名前、メールアドレス、電話番号の3つの入力を受け取ります。2つの Contact インスタンスを作成してください:
    • 1つ目の連絡先は、3つの値すべて(名前、メール、電話)を使用します。
    • 2つ目の連絡先は、名前とメールのみを使用します(電話番号はデフォルト値に依存します)。
    以下の4行を出力してください:
    • 1つ目の連絡先の詳細(full details)
    • 1つ目の連絡先の概要(summary)
    • 2つ目の連絡先の詳細(full details)
    • 2つ目の連絡先の概要(summary)

コンストラクタのプロモーションによって、プロパティの定義、可視性の設定、型の宣言、および値の代入を、単一の読みやすいコンストラクタシグネチャでどのように行えるかに注目してください。デフォルト値を持つオプションの電話番号パラメータは、プロモーションされたパラメータが通常のパラメータと同様にデフォルト値とシームレスに機能することを示しています。

チートシート

PHP 8.0ではコンストラクタのプロパティ昇格(constructor promotion)が導入されました。これにより、アクセス修飾子を追加することで、コンストラクタの引数内でクラスプロパティの宣言と初期化を直接行うことができます。

従来のアプローチ:

<?php
class Product {
    private string $name;
    private float $price;
    
    public function __construct(string $name, float $price) {
        $this->name = $name;
        $this->price = $price;
    }
}

コンストラクタのプロパティ昇格を使用した場合:

<?php
class Product {
    public function __construct(
        private string $name,
        private float $price
    ) {}
}

$product = new Product("Laptop", 999.99);

コンストラクタの引数の前に privateprotected、または public を追加することで、PHPは自動的にプロパティを作成し、値を割り当てます。

昇格された引数にはデフォルト値を使用することもできます:

<?php
class Contact {
    public function __construct(
        private string $name,
        private string $email,
        private string $phone = "Not provided"
    ) {}
}

コンストラクタのプロパティ昇格は通常の引数と混ぜて使用することができ、必要に応じてコンストラクタのボディ内にロジックを追加することも可能です。

自分で試してみよう

<?php

require_once 'Contact.php';

// 入力を読み込む
$name = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$phone = trim(fgets(STDIN));

// TODO: 3つの値(名前、メール、電話番号)を使用して最初の連絡先を作成する

// TODO: 名前とメールのみを使用して2番目の連絡先を作成する(デフォルトの電話番号を使用)

// TODO: 最初の連絡先の詳細をすべて表示する

// TODO: 最初の連絡先の概要を表示する

// TODO: 2番目の連絡先の詳細をすべて表示する

// TODO: 2番目の連絡先の概要を表示する

?>
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン