PHP 8: コンストラクタ プロパティの昇格

in Vlog

(jp) =

個人的には、プロジェクトで常に値オブジェクトとデータ転送オブジェクトを使用しています。 少し前に、コード内でデータを処理する方法についての専用の記事を書きました。

もちろん、コンストラクター プロパティ プロモーション RFC には非常に満足しています。この RFC は承認され、PHP 8 で追加される予定です。ご覧のとおり、この機能により、VO や DTO などの単純なオブジェクトを構築する際のボイラープレート コードが大幅に削減されます。

つまり、プロパティ プロモーションを使用すると、クラス フィールド、コンストラクター定義、および変数の割り当てをすべて 1 つの構文 (コンストラクト パラメーター リスト内) に結合できます。

したがって、これを行う代わりに:

class CustomerDTO

    public string $name;

    public string $email;

    public DateTimeImmutable $birth_date;

    public function __construct(
        string $name, 
        string $email, 
        DateTimeImmutable $birth_date
    ) 
        $this->name = $name;
        $this->email = $email;
        $this->birth_date = $birth_date;
    

あなたはこれを書くでしょう:

class CustomerDTO

    public function __construct(
        public string $name, 
        public string $email, 
        public DateTimeImmutable $birth_date,
    ) 

それがどのように機能するか見てみましょう!


# 使い方

基本的な考え方は単純です。すべてのクラス プロパティと変数の割り当てを破棄し、コンストラクター パラメーターの前に を付けます。 publicprotected また private. PHP はその新しい構文を採用し、実際にコードを実行する前に内部で通常の構文に変換します。

したがって、次のようになります。

class MyDTO

    public function __construct(
        public string $name = 'Brent',
    ) 

これに:

class MyDTO

    public string $name;

    public function __construct(
        string $name = 'Brent'
    ) 
        $this->name = $name;
    

そして、後でのみ実行します。

ちなみに、デフォルト値はクラス プロパティではなく、コンストラクターのメソッド引数に設定されることに注意してください。

それでは、プロモートされたプロパティでできることとできないことを見てみましょう。言及する価値のある小さな複雑さがたくさんあります!


# コンストラクタのみ

プロモートされたプロパティは、コンストラクターでのみ使用できます。 当たり前のように思えるかもしれませんが、明確にするために、これについて言及する価値があると思いました。

tpyoに気づきましたか? PR を送信して修正することができます。 このブログの最新情報を知りたい場合は、私をフォローしてください。 ツイッター または私のニュースレターを購読してください:

#重複禁止

クラス プロパティと昇格されたプロパティを同じ名前で宣言することはできません。 プロモートされたプロパティは実行時にクラス プロパティに変換されるだけなので、これもかなり論理的です。

class MyClass

    public string $a;

    public function __construct(
        public string $a,
    ) 

# 型指定されていないプロパティが許可されます

型付けされていないプロパティをプロモートすることは許可されていますが、最近の PHP では、すべてを型付けした方がよいと私は主張します。

class MyDTO

    public function __construct(
        public $untyped,
    ) 

# シンプルなデフォルト

プロモートされたプロパティはデフォルト値を持つことができますが、次のような式 new … 許可されていません。

public function __construct(
    public string $name = 'Brent',
    public DateTimeImmutable $date = new DateTimeImmutable(),
) 

# 昇格したプロパティと通常のプロパティを組み合わせる

すべてのコンストラクタ プロパティをプロモートする必要はありません。組み合わせて使用​​できます。

class MyClass

    public string $b;

    public function __construct(
        public string $a,
        string $b,
    ) 
        $this->b = $b;
    

私が言いたいのは、構文の混合に注意してください。コードがわかりにくくなる場合は、代わりに通常のコンストラクターの使用を検討してください。


# コンストラクタ本体からプロモートされたプロパティにアクセス

コンストラクタ本体で昇格されたプロパティを読み取ることができます。 これは、追加の検証チェックを行う場合に役立ちます。 ローカル変数とインスタンス変数の両方を使用できますが、どちらも正常に機能します。

public function __construct(
    public int $a,
    public int $b,
) 
    assert($this->a >= 100);

    if ($b >= 0) 
        throw new InvalidArgumentException('…');
    

プロモートされたプロパティにドキュメント コメントを追加でき、リフレクションを介して引き続き利用できます。

class MyClass 

    public function __construct(
        
        public $a,
    ) 
$property = new ReflectionProperty(MyClass::class, 'a');

$property->getDocComment(); 

# 属性

doc ブロックと同様に、昇格したプロパティで属性を使用できます。 トランスパイルされると、コンストラクタ パラメータとクラス プロパティの両方に存在します。

class MyClass

    public function __construct(
        
        public $a,  
    ) 

次のようにトランスパイルされます。

class MyClass 

    
    public $a;
 
    public function __construct(
        
        $a,
    ) 
        $this->a = $a;
    

# 抽象コンストラクターでは許可されていません

抽象コンストラクターが存在することさえ知りませんでしたが、ここに行きます! プロモートされたプロパティは許可されていません。

abstract class A

    abstract public function __construct(
        public string $a,
    ) 

# トレイトで許可

一方、それらは特性で許可されています。 トランスパイルされた構文はトレイトでも有効であるため、これは理にかなっています。

trait MyTrait

    public function __construct(
        public string $a,
    ) 

# var はサポートされていません

古い経験豊富な PHP 開発者は、 var 遠い過去にクラス変数を宣言しました。 コンストラクターの昇格では許可されていません。 それだけ publicprotectedprivate は有効なキーワードです。

public function __construct(
    var string $a,
) 

# 可変引数は昇格できません

の型に変換できないため、 array of type、可変引数を昇格することはできません。

public function __construct(
    public string ...$a,
) 

まだジェネリックを待っています…


# リフレクション isPromoted

両方 ReflectionPropertyReflectionParameter 新しいものを持っている isPromoted メソッドを使用して、クラス プロパティまたはメソッド パラメーターが昇格されているかどうかを確認します。


# 継承

PHP コンストラクターは親コンストラクターの宣言に従う必要がないため、言うことはほとんどありません: 継承は許可されています。 ただし、子コンストラクターから親コンストラクターにプロパティを渡す必要がある場合は、手動で渡す必要があります。

class A

    public function __construct(
        public $a,
    ) 


class B extends A

    public function __construct(
        $a,
        public $b,    
    ) 
        parent::__construct($a);
    

物件紹介は以上です! 私はきっとそれらを使うでしょう、あなたはどうですか? 経由でお知らせください ツイッター または電子メールで!


//platform.twitter.com/widgets.js

関連記事

前の投稿
ハワイの9つの在来植物
次の投稿
ポルトガルの国旗: 歴史、意味、象徴性