ホームページ >バックエンド開発 >PHPチュートリアル >PHPで厳密に型付けされた配列とコレクションを作成します

PHPで厳密に型付けされた配列とコレクションを作成します

Christopher Nolan
Christopher Nolanオリジナル
2025-02-10 11:20:11134ブラウズ

PHPで厳密に型付けされた配列とコレクションを作成します

キーテイクアウト

  • PHP 5.6は、…トークンを使用してタイプ付き配列を作成する機能を導入しました。これは、関数またはメソッドがさまざまな長さの引数を受け入れることを示します。この機能をタイプのヒントと組み合わせて、特定の種類のオブジェクトのみが配列で受け入れられるようにすることができます。 この機能の制限の1つは、メソッドごとに定義できるタイプアレイが1つだけであることです。これを克服するために、入力された配列を「コレクション」クラスに注入することができます。これにより、GETメソッドの「配列」よりも具体的なリターンタイプも可能になります。
  • 値オブジェクトは、カスタム検証に使用できます。たとえば、定格値を制約で作成して、評価が常に0〜5であることを確認できます。これにより、各注入オブジェクトの上にループすることなく、個々のコレクションメンバーの追加の検証が提供されます。
  • 厳密にタイプされた配列とコレクションには、いくつかの利点があります。それらは、1つの場所で簡単なタイプの検証を提供し、構造時に値が常に検証されていることを確認し、コレクションごとのカスタムロジックの追加を可能にし、メソッドシグネチャの引数を混合する確率を減らします。
  • 最初の構築後にコレクションと値オブジェクトの値の編集を容易にする方法を追加することは可能ですが、変更を行う必要があるときにそれらを不変に保ち、プリミティブタイプに変換する方が効率的です。変更を加えた後、コレクションまたはバリューオブジェクトを更新された値で再構築することができます。これは再度検証されます。
  • この投稿は最初にMediumに掲載され、著者の許可を得てここに再発行されました。私たちはあなたがメディアでバートをフォローし、彼にそこにいくつかの好きなものを与えることをお勧めします!
  • PHP 5.6で発表された言語機能の1つは、関数または方法がさまざまな長さの引数を受け入れることを示すために...トークンの追加でした。
  • 私がめったに述べていないことは、この機能とタイプのヒントを組み合わせて、本質的に型付けられた配列を作成することが可能であるということです。 たとえば、
dateTimeimmutableオブジェクトのみを受け入れる空気日付の配列を設定する方法を備えた映画のクラスを持つことができます。

さまざまな数の個別のdateTimeImmutableオブジェクトをsetairdatesに渡すことができます()方法:


dateTimeImmutable以外の何かを渡す場合、たとえば、致命的なエラーがスローされます。

代わりに、setimedates()に渡したいデータティメイムミュート可能なオブジェクトの配列がすでにある場合、もう一度...トークンを使用できますが、今回はそれらを解き放つことができます。

配列に予想されるタイプではない値が含まれている場合でも、前述の致命的なエラーが得られます。

さらに、スカラータイプをPHP 7から始めるのと同じ方法で使用できます。たとえば、映画のクラスにフロートとして評価のリストを設定する方法を追加できます。

<span><span><?php
</span></span><span>
</span><span><span>class Movie {  
</span></span><span>  <span>private $dates = [];
</span></span><span>
</span><span>  <span>public function setAirDates(\DateTimeImmutable ...$dates) {
</span></span><span>    <span>$this->dates = $dates;
</span></span><span>  <span>}
</span></span><span>
</span><span>  <span>public function getAirDates() {
</span></span><span>    <span>return $this->dates;
</span></span><span>  <span>}
</span></span><span><span>}
</span></span>
繰り返しますが、これにより、評価プロパティには、すべてのコンテンツをループして検証することなく、常にフロートが含まれます。そのため、無効なタイプを心配することなく、getAverAgreating()で数学操作を簡単に実行できます。 この種のタイプアレイの問題

この機能を型付けされた配列として使用する欠点の1つは、メソッドごとのそのような配列のみを定義できることです。オプションの方法で後で設定するのではなく、コンストラクターの評価のリストと一緒に空気日付のリストを期待する映画のクラスを望んでいたとしましょう。これは、上記の方法では不可能です

別の問題は、PHP 7を使用する場合、get()メソッドのリターンタイプは「配列」である必要があることです。これはしばしば一般的すぎます。

ソリューション:コレクションクラス

両方の問題を修正するために、いわゆる「コレクション」クラス内に型付けされた配列を単純に挿入できます。これにより、懸念の分離も改善されます。これは、平均評価の計算方法を関連するコレクションクラスに移動できるようにするためです。

コンストラクターに変数の長さを持つタイプされた引数のリストをまだ使用していることに注意してください。

このコレクションクラスをForeachループで使用する機能が必要な場合は、IteratorAggregateインターフェイスを実装する必要があります。

先に進むと、空気日付のリストのコレクションを作成することもできます。
<span><span><?php
</span></span><span>
</span><span><span>$movie = new Movie();
</span></span><span>
</span><span><span>$movie->setAirDates(
</span></span><span>  <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-01-28'),
</span></span><span>  <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-02-22')
</span></span><span><span>);
</span></span>

映画のクラスにパズルのすべてのピースをまとめると、コンストラクターに2つの個別に入力されたコレクションを注入できるようになりました。さらに、GETメソッドの「配列」よりも具体的なリターンタイプを定義できます。

カスタム検証に値オブジェクトを使用して

評価に追加の検証を追加したい場合は、さらに一歩進んで、いくつかのカスタム制約を備えた評価値オブジェクトを定義することができます。たとえば、評価は0〜5の間で制限される可能性があります:
<span><span><?php
</span></span><span>
</span><span><span>$dates = [
</span></span><span>  <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-01-28'),
</span></span><span>  <span><span>\DateTimeImmutable</span>::createFromFormat('Y-m-d', '2017-02-22'),
</span></span><span><span>];
</span></span><span>
</span><span><span>$movie = new Movie();
</span></span><span><span>$movie->setAirDates(...$dates);
</span></span>

レーティングコレクションクラスに戻って、フロートの代わりにこれらの値オブジェクトを使用するためにいくつかの小さな変更を行う必要があります。
<span><span><?php
</span></span><span>
</span><span><span>declare(strict_types=1);
</span></span><span>
</span><span><span>class Movie {
</span></span><span>  <span>private $dates = [];
</span></span><span>  <span>private $ratings = [];
</span></span><span>
</span><span>  <span>public function setAirDates(\DateTimeImmutable ...$dates) { /* ... */ }
</span></span><span>  <span>public function getAirDates() : array { /* ... */ }
</span></span><span>
</span><span>  <span>public function setRatings(float ...$ratings) {
</span></span><span>    <span>$this->ratings = $ratings;
</span></span><span>  <span>}
</span></span><span>
</span><span>  <span>public function getAverageRating() : float {
</span></span><span>    <span>if (empty($this->ratings)) {
</span></span><span>      <span>return 0;
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>$total = 0;
</span></span><span>
</span><span>    <span>foreach ($this->ratings as $rating) {
</span></span><span>      <span>$total += $rating;
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>return $total / count($this->ratings);
</span></span><span>  <span>}
</span></span><span><span>}
</span></span>
この方法で、各コレクションメンバーの追加の検証を取得しますが、まだ注入された各オブジェクトの上にループする必要はありません。

利点

<span><span><?php
</span></span><span>
</span><span><span>declare(strict_types=1);
</span></span><span>
</span><span><span>class Ratings {
</span></span><span>  <span>private $ratings;
</span></span><span>
</span><span>  <span>public function __construct(float ...$ratings) {
</span></span><span>    <span>$this->ratings = $ratings;
</span></span><span>  <span>}
</span></span><span>
</span><span>  <span>public function getAverage() : float {
</span></span><span>    <span>if (empty($this->ratings)) {
</span></span><span>      <span>return 0;
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>$total = 0;
</span></span><span>
</span><span>    <span>foreach ($this->ratings as $rating) {
</span></span><span>      <span>$total += $rating;
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>return $total / count($this->ratings);
</span></span><span>  <span>}
</span></span><span><span>}
</span></span>
これらの個別のコレクションクラスとバリューオブジェクトを入力すると、多くの作業のように思えるかもしれませんが、一般的な配列とスカラー値よりもいくつかの利点があります。

1つの場所での簡単なタイプ検証。コレクションメンバーのタイプを検証するために、アレイを手動でループする必要はありません。

  • アプリケーションでこれらのコレクションとバリューオブジェクトを使用している場合は、それらの価値が常に建設時に検証されていることがわかっています。たとえば、格付けは常に0〜5;

  • コレクションごとのカスタムロジックおよび/または値オブジェクトを簡単に追加できます。たとえば、getaverage()メソッド。アプリケーション全体を通して再利用できます;

  • 単一の関数またはメソッドに複数のタイプされたリストを注入する可能性があります。これは、最初にコレクションクラスに値を注入せずに...トークンを使用することはできません。

  • メソッドシグネチャに引数を混合するオッズは大幅に減少しています。たとえば、評価のリストと空気日付のリストの両方を注入する場合、ジェネリック配列を使用すると、建設時に2つは偶然に簡単に混同される可能性があります。
  • 編集はどうですか?

  • 今では、最初の構築後にコレクションとバリューオブジェクトの価値をどのように変更できるか疑問に思うかもしれません。 編集を容易にする方法を追加できますが、タイプのヒントの利点を維持するために各コレクションのほとんどの方法を複製する必要があるため、これはすぐに面倒になります。たとえば、定格のADD()メソッドは評価オブジェクトのみを受け入れる必要がありますが、AID()メソッドはADR()メソッドがDateTimeImmutableオブジェクトのみを受け入れる必要があります。これにより、これらの方法のインターフェースや再利用が非常に困難になります。

    代わりに、コレクションとバリューオブジェクトを単に不変に保ち、変更を行う必要があるときにそれらをプリミティブタイプに変換することができます。変更が完了した後、更新された値で必要なコレクションまたはバリューオブジェクトを簡単に再構築できます。 (再)構築すると、すべてのタイプが再び検証され、定義した可能性のある追加の検証とともに たとえば、

    コレクションにSimple ToArray()メソッドを追加して、次のような変更を加えることができます。

    この方法では、array_filter()などの既存の配列機能を再利用することもできます。

    コレクションオブジェクト自体で編集を行う必要がある場合は、必要な方法で必要な方法で必要な方法で必要な方法で追加できます。ただし、それらのほとんどは、指定された引数のタイプ検証を行う必要があるため、すべての異なるコレクションクラスでそれらを再利用することは困難です。

    ジェネリックメソッドの再利用

    ご存知かもしれませんが、すべてのtoarray()とgetiterator()の両方を実装することにより、コレクションクラス全体でコードの複製を取得しています。幸いなことに、これらの方法は一般的な親クラスに移動するのに十分な一般的なものです。

    コレクションクラスに残されるのは、コンストラクターのタイプ検証と、このようなコレクションに固有のオプションの追加ロジックだけです。
    <span><span><?php
    </span></span><span>
    </span><span><span>class Movie {  
    </span></span><span>  <span>private $dates = [];
    </span></span><span>
    </span><span>  <span>public function setAirDates(\DateTimeImmutable ...$dates) {
    </span></span><span>    <span>$this->dates = $dates;
    </span></span><span>  <span>}
    </span></span><span>
    </span><span>  <span>public function getAirDates() {
    </span></span><span>    <span>return $this->dates;
    </span></span><span>  <span>}
    </span></span><span><span>}
    </span></span>

    オプションで、私たちのタイプの検証を元に戻すことができる方法で、子供のクラスがバリュープロパティをいじるのを防ぐために、コレクションを最終的にすることができました。

    結論

    まだ完璧ではありませんが、最近のPHPのリリースを含むコレクションとバリューオブジェクトのタイプ検証で着実に作業しやすくなっています。

    理想的には、再利用可能なコレクションクラスの作成をさらに容易にするために、将来のPHPで何らかの形のジェネリックを取得します。

    値オブジェクトの使用を大幅に改善する機能は、文字列に加えて、異なるプリミティブタイプにオブジェクトをキャストする機能です。これは、__toint()、__tofloat()などのように、__toString()に匹敵する追加の魔法の方法を追加することで簡単に実装できます。

    幸いなことに、後のバージョンで両方の機能を実装する可能性があるため、いくつかのRFCが進行中であるため、指が交差しました! ?

    generics:https://wiki.php.net/rfc/generics

    • ジェネリック配列:https://wiki.php.net/rfc/generic-arrays

    • スカラーへのオブジェクトのキャスト:https://wiki.php.net/rfc/class_casting_to_scalar

    • このチュートリアルが役立つと感じた場合は、メディアの元の投稿にアクセスして、❤️を付けてください。フィードバック、質問、またはコメントがある場合は、以下または元の投稿に回答として残してください。
    • PHPで厳密にタイプされた配列とコレクションの作成に関するよくある質問(FAQ)
    phpで厳密に型付けされた配列を使用することの利点は何ですか?
    ​​

    phpの厳密に型付けされた配列は、配列内のすべての要素が特定のタイプであることを確認する方法を提供します。これは、データの一貫性が非常に重要なより大きく、より複雑なアプリケーションで特に役立ちます。配列内のすべての要素の特定のタイプを実施することにより、予期しないデータ型のために発生する可能性のある潜在的なバグやエラーを防ぐことができます。また、使用しているデータの種類を常に知っているので、コードをより予測可能でデバッグしやすくします。厳密にタイプされた配列をネイティブにサポートしていません。ただし、配列に追加された要素をタイプチェックするクラスを作成することができます。このクラスには、要素を追加および取得する方法があり、これらの方法は操作を実行する前に要素のタイプをチェックします。要素のタイプが予想されるタイプと一致しない場合、エラーがスローされます。

    PHPの配列でタイプヒントを使用できますか?関数またはメソッドは、関数またはメソッド宣言の引数名の前に「配列」を追加することにより、引数として配列を期待することを指定できます。ただし、これにより、引数が配列であることのみが保証され、配列内のすべての要素が特定のタイプであるということではありません。

    ゆるく型付けされた型と厳密に型付けされた配列の違いは何ですか?

    ゆるく入力された配列では、要素は任意のタイプにできます。厳密にタイプした配列では、すべての要素が特定のタイプでなければなりません。別のタイプの要素を厳密に入力した配列に追加しようとすると、エラーがスローされます。 PHPは「declare(strict_types = 1);」を使用して使用します。 PHPファイルの先頭にある指令。これにより、ファイル内のすべての関数呼び出しと戻りステートメントの厳密なタイプチェックが強制されます。 Arrayに追加されたオブジェクトをタイプチェックするクラスを作成することにより、PHPのオブジェクトのオブジェクト。クラスにはオブジェクトを追加および取得する方法があり、これらの方法は操作を実行する前にオブジェクトのタイプを確認します。 PHPで厳密にタイプされた配列の主な制限は、PHPがネイティブにサポートしていないため、実装するために追加のコードが必要であることです。これにより、コードがより複雑で維持が難しくなる可能性があります。さらに、Strictlyタイピングされた配列は、異なるタイプの要素を許可しないため、ゆるく型付けされた配列よりも柔軟性が低下する可能性があります。 PHPの多次元配列を使用して、タイプヒントを使用できます。ただし、PHPのタイプは、引数が配列であることのみを保証し、配列(またはサブアレイ)のすべての要素が特定のタイプであることを保証します。 php?

    ​​

    Strictlyと入力された配列をPHPで使用する場合、トライキャッチブロックを使用してエラーを処理できます。アレイに要素を追加するときにエラーが発生した場合(たとえば、要素が間違ったタイプの場合)、例外がスローされます。この例外をキャッチして適切に処理できます。

    PHPの組み込み配列関数を備えたStrictlyタイプの配列を使用できますか?関数。ただし、これらの関数はタイプチェックを強制しないため、注意する必要があります。配列を変更して間違ったタイプの要素を追加する関数を使用すると、これはエラーにつながる可能性があります。

    以上がPHPで厳密に型付けされた配列とコレクションを作成しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。