te16

PHP 7.4 の型付きプロパティ

(jp) =

型付きクラス プロパティが追加されました PHP 7.4 大幅な改善を提供します PHPの型システム。 これらの変更は完全にオプトインであり、以前のバージョンを壊すものではありません。

この投稿では、この機能を詳しく見ていきますが、まず最も重要なポイントを要約することから始めましょう。

  • それらは現在利用可能です PHP 7.4、2019年11月発売予定
  • これらはクラスでのみ使用でき、アクセス修飾子が必要です。 publicprotected また private; また var
  • を除くすべてのタイプが許可されます。 voidcallable

実際の動作は次のとおりです。

class Foo

    public int $a;

    public ?string $b = 'foo';

    private Foo $prop;

    protected static string $static = 'default';

型の付加的なメリットがよくわからない場合は、まずこの投稿を読むことをお勧めします。

# 未初期化

楽しいことを見る前に、型指定されたプロパティについて、最初に説明することが不可欠な重要な側面があります。

一見するとどう思うかもしれませんが、次のコードは有効です。

class Foo

    public int $bar;


$foo = new Foo;

の値にもかかわらず、 $bar のオブジェクトを作成した後、整数ではありません FooPHP 場合にのみエラーをスローします $bar アクセスされます:

var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization

エラー メッセージから読み取れるように、新しい種類の「変数状態」があります: 初期化されていません。

もしも $bar タイプがありませんでした。その値は単純に null. ただし、型は null 許容になる可能性があるため、型指定された null 許容プロパティが設定されているのか、単に忘れられているのかを判断することはできません。 そのため、「未初期化」が追加されました。

uninitialized について覚えておくべき重要なことが 4 つあります。

  • 初期化されていないプロパティから読み取ることはできません。これを行うと、致命的なエラーが発生します。
  • プロパティにアクセスするときに初期化されていない状態がチェックされるため、その型が null 非許容であっても、初期化されていないプロパティを持つオブジェクトを作成できます。
  • 読み取る前に、初期化されていないプロパティに書き込むことができます。
  • 使用する unset 型指定されたプロパティを設定すると初期化されなくなりますが、型指定されていないプロパティを設定解除すると初期化されます null.

特に、オブジェクトの作成後に初期化されていない null 非許容のプロパティが設定されている次のコードは有効であることに注意してください。

class Foo

    public int $a;


$foo = new Foo;

$foo->a = 1;

初期化されていない状態はプロパティの値を読み取るときにのみチェックされますが、型の検証はプロパティに書き込むときに行われます。 これは、無効な型がプロパティの値になることはないと確信できることを意味します。

# デフォルトとコンストラクタ

型付きの値を初期化する方法を詳しく見てみましょう。 スカラー型の場合、デフォルト値を提供することが可能です:

class Foo

    public int $bar = 4;
    
    public ?string $baz = null;
    
    public array $list = [1, 2, 3];

のみ使用できることに注意してください。 null 型が実際に null 許容である場合のデフォルトとして。 これは明らかなように思えるかもしれませんが、次のことが許可されているパラメーターの既定値には、従来の動作がいくつかあります。

function passNull(int $i = null)
  

passNull(null);

幸いなことに、この紛らわしい動作は型付きプロパティでは許可されていません。

また、デフォルト値を持つことは不可能であることに注意してください object またはクラスの種類。 コンストラクタを使用してデフォルトを設定する必要があります。

型付きの値を初期化する明白な場所は、もちろんコンストラクターです。

class Foo

    private int $a;

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

ただし、前に述べたことも覚えておいてください。コンストラクターの外部で、初期化されていないプロパティに書き込むことは有効です。 プロパティから何も読み取っていない限り、初期化されていないチェックは実行されません。

# 型の種類

では、正確には何をどのように入力できるのでしょうか? 型付きプロパティは (今のところ) クラスでのみ機能し、アクセス修飾子または var その前にキーワード。

利用可能なタイプの時点で、ほとんどすべてのタイプが使用できます。 voidcallable.

なぜなら void は値がないことを意味しますが、値を入力するために使用できないことは理にかなっています。
callable ただし、もう少し微妙です。

の「callable」を参照してください PHP 次のように記述できます。

$callable = [$this, 'method'];

次の(壊れた)コードがあるとします。

class Foo

    public callable $callable;
    
    public function __construct(callable $callable)
      


class Bar

    public Foo $foo;
    
    public function __construct()
    
        $this->foo = new Foo([$this, 'method'])
    
    
    private function method()
      


$bar = new Bar;

($bar->foo->callable)();

この例では、 $callable プライベートを指す Bar::method、しかしのコンテキスト内で呼び出されます Foo. この問題のため、追加しないことにしました callable サポート。

大したことじゃないんだけど、 Closure は有効な型であり、 $this 構築されたコンテキスト。

邪魔にならないので、利用可能なすべてのタイプのリストを次に示します。

  • ブール
  • 整数
  • 浮く
  • ストリング
  • 配列
  • 反復可能
  • 物体
  • ? (ヌル可能)
  • 自分と親
  • クラスとインターフェース

# 強制型と厳密型

PHPは、私たちが好きで嫌いな動的言語であるため、可能な限り型を強制または変換しようとします。 整数が必要な場所に文字列を渡すとします。 PHP その文字列を自動的に変換しようとします:

function coerce(int $i)
  

coerce('1'); 

型付きプロパティにも同じ原則が適用されます。 次のコードは有効で、変換されます '1'1.

class Bar

    public int $i;


$bar = new Bar;

$bar->i = '1'; 

この動作が気に入らない場合は、厳密な型を宣言して無効にすることができます。

declare(strict_types=1);

$bar = new Bar;

$bar->i = '1'; 

Fatal error: Uncaught TypeError: 
Typed property Bar::$i must be int, string used

# タイプの差異と継承

それでも PHP 7.4 型分散の改善が導入されましたが、型付きプロパティは依然として不変です。 これは、以下が無効であることを意味します。

class A 
class B extends A 

class Foo

    public A $prop;


class Bar extends Foo

    public B $prop;


Fatal error: Type of Bar::$prop must be A (as in class Foo)

上記の例が重要でないように思われる場合は、次を参照してください。

class Foo

    public self $prop;


class Bar extends Foo

    public self $prop;

PHP 交換します self コードを実行する前に、それが参照する具象クラスの舞台裏。 これは、この例で同じエラーがスローされることを意味します。 それを処理する唯一の方法は、次のことです。

class Foo

    public Foo $prop;


class Bar extends Foo

    public Foo $prop;

継承といえば、継承されたプロパティの型を上書きする適切なユース ケースを思いつくのは難しいかもしれません。

私はその意見に同意しますが、継承されたプロパティの型を変更することは可能ですが、アクセス修飾子も変更された場合に限ります。 privateprotected また public.

次のコードは有効です。

class Foo

    private int $prop;


class Bar extends Foo

    public string $prop;

ただし、型を null 許容から null 非許容に、またはその逆に変更することは許可されていません。

class Foo

    public int $a;
    public ?int $b;


class Bar extends Foo

    public ?int $a;
    public int $b;


Fatal error: Type of Bar::$a must be int (as in class Foo)

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

#まだまだあります!

この投稿の冒頭で述べたように、型付きプロパティは 選考科目 に加えて PHP. それらについては、まだまだ言いたいことがたくさんあります。 をお読みになることをお勧めします。 RFC すべてのきちんとした細部を知るために。

初めての方は PHP 7.4、変更と追加された機能の完全なリストをお読みになることをお勧めします。 正直なところ、これは過去最高のリリースの 1 つであり、時間を費やす価値があります。

最後に、このトピックについて共有したいご意見がありましたら、ぜひお聞かせください。 あなたは私に連絡することができます ツイッター または電子メール。

次回まで!

次の投稿
アラバマ州で最も寒い場所を発見 (-61°F!)
前の投稿
ボリビアの国旗: 歴史、意味、象徴性

ノート:

AZ: 動物の世界、ペット、ペット、野生の自然に関するカテゴリー記事…
SP:スポーツカテゴリー。
New vs Ne: ニュースコラム。
Te: テクノロジー カテゴリ。
Gt:エンターテインメントカテゴリー。
Bt: 占い、星占い、超常現象、超常現象。
Ta:人生コラム。