PHP の配列仕様とカスタム コレクション
これはほぼ 配列設計 のスタイル ガイドですが、これを オブジェクト デザイン スタイル ガイド に追加するのは違和感があります。そう、すべてのオブジェクト指向言語が動的配列を持っているわけではないからです。 PHP は Java (よく知られているかもしれません) によく似ているため、この記事の例は PHP で書かれていますが、組み込みのコレクション クラスやインターフェイスの代わりに動的配列を使用します。
配列をリストとして使用する
すべての要素は同じ型である必要があります
リストとしての配列 リスト (特定の順序での値のコレクション) の場合、各値は z:
$goodList = [ 'a', 'b' ]; $badList = [ 'a', 1 ];
型である必要があります。リスト型に注釈を付けるための一般的に受け入れられているスタイルは次のとおりです:@var配列<TypeOfElement>
。インデックスのタイプを追加しないように注意してください (常に int
です)。
各要素のインデックスは無視してください。
PHP は、リスト内の各要素 (0、1、2 など) に新しいインデックスを自動的に作成します。ただし、これらのインデックスに依存したり、直接使用したりしないでください。クライアントが依存する必要があるリストのプロパティは、iterable と countable だけです。
したがって、foreach
と count()
を自由に使用できますが、リスト内の要素をループするために for
を使用しないでください。
// 好的循环: foreach ($list as $element) { } // 不好的循环 (公开每个元素的索引): foreach ($list as $index => $element) { } // 也是不好的循环 (不应该使用每个元素的索引): for ($i = 0; $i < count($list); $i++) { }
(PHP では、リスト内のインデックスが欠落していたり、リスト内の要素よりも多くのインデックスが存在したりする可能性があるため、for
ループは機能しない場合もあります。)
要素を削除する代わりにフィルターを使用する
インデックス (unset()
) によってリストから要素を削除することもできますが、次のように使用する必要があります。 array_filter( )
要素を削除する代わりに、(不要な要素を除いた) 新しいリストを作成します。
同様に、要素のインデックスに依存すべきではないため、array_filter()
を使用する場合は、要素をフィルタリングするために flag
パラメータを使用しないでください。インデックス、さらに要素とインデックスに基づいて要素をフィルタリングします。
// 好的过滤: array_filter( $list, function (string $element): bool { return strlen($element) > 2; } ); // 不好的过滤器(也使用索引来过滤元素) array_filter( $list, function (int $index): bool { return $index > 3; }, ARRAY_FILTER_USE_KEY ); // 不好的过滤器(同时使用索引和元素来过滤元素) array_filter( $list, function (string $element, int $index): bool { return $index > 3 || $element === 'Include'; }, ARRAY_FILTER_USE_BOTH );
キー がインデックス (0、1、2 など) ではなく
に関連している場合、配列をマップとして使用します。配列をマップとして自由に使用できます (マップから値を一意のキーで取得できます)。
すべてのキーは同じ型である必要があります
配列をマップとして使用する最初のルールは、配列内のすべてのキーが同じ型である必要があります (最も一般的なもの) 1 つはタイプ string
のキーです)。
$goodMap = [ 'foo' => 'bar', 'bar' => 'baz' ]; // 不好(使用不同类型的键) $badMap = [ 'foo' => 'bar', 1 => 'baz' ];
すべての値は同じ型でなければなりません
マップ内の値についても同様であり、同じ型である必要があります。
$goodMap = [ 'foo' => 'bar', 'bar' => 'baz' ]; // 不好(使用不同类型的值) $badMap = [ 'foo' => 'bar', 'bar' => 1 ];
一般的に受け入れられているマッピング タイプの注釈スタイルは、@var array<typeofkey typeofvalue></typeofkey>
です。
マップはプライベートに保つ必要があります。
リストはその単純な特性により、オブジェクト間で安全に受け渡すことができます。すべてのクライアントは、リストが空であっても、これを使用して要素をループしたり、要素をカウントしたりできます。クライアントは対応する値を持たないキーに依存する可能性があるため、マッピングの処理はさらに困難になります。これは、一般に、それらを管理するオブジェクトに対してプライベートにしておく必要があることを意味します。クライアントは内部マッピングに直接アクセスすることはできません。代わりに、値を取得するためにゲッター (場合によってはセッター) が提供されます。要求されたキーの値が存在しない場合、例外がスローされます。ただし、マップとその値を完全に非公開にできる場合は、そうしてください。
// 公开一个列表是可以的 /** * @return array<User> */ public function allUsers(): array { // ... } // 公开地图可能很麻烦 /** * @return array<string, User> */ public function usersById(): array { // ... } // 相反,提供一种方法来根据其键检索值 /** * @throws UserNotFound */ public function userById(string $id): User { // ... }
複数の値タイプのマッピングにはオブジェクトを使用する
異なる タイプの 値を 1 つのマッピングに格納したい場合は、を使用してくださいオブジェクト。クラスを定義し、そのクラスに型指定されたパブリック プロパティを追加するか、コンストラクターとゲッターを追加します。このようなオブジェクトの例は、構成オブジェクトやコマンド オブジェクトです。
final class SillyRegisterUserCommand { public string $username; public string $plainTextPassword; public bool $wantsToReceiveSpam; public int $answerToIAmNotARobotQuestion; }
これらの規則の例外
場合によっては、ライブラリまたはフレームワークは、より動的に配列を使用する必要があります。方法 。このような場合、以前のルールに従うことは不可能です (また望ましくない)。たとえば、データベーステーブルに保存される配列データや、Symfony フォーム設定などです。
自定义集合类
自定义集合类是一种非常酷的方法,最后可以和Iterator
、ArrayAccess
和其朋友一起使用,但是我发现大多数生成的代码令人很困惑。第一次查看代码的人必须在 PHP 手册中查找详细信息,即使他们是有经验的开发人员。另外,你需要编写更多的代码,你必须维护这些代码(测试、调试等)。所以在大多数情况下,我发现一个简单的数组,加上一些适当的类型注释,就足够了。到底什么是需要将数组封装到自定义集合对象中的强信号?
- 如果你发现与那个数组相关的逻辑被复制了。
- 如果你发现客户端必须处理太多关于数组内部内容的细节。
使用自定义集合类来防止重复逻辑
如果使用相同数组的多个客户端执行相同的任务(例如过滤、映射、减少、计数),则可以通过引入自定义集合类来消除重复。将重复的逻辑移到集合类的一个方法上,允许任何客户端使用对集合的简单方法调用来执行相同的任务:
$names = [/* ... */]; // 在几个地方发现: $shortNames = array_filter( $names, function (string $element): bool { return strlen($element) < 5; } ); // 变成一个自定义集合类: use Assert\Assert; final class Names { /** * @var array<string> */ private array $names; public function __construct(array $names) { Assert::that()->allIsString($names); $this->names = $names; } public function shortNames(): self { return new self( array_filter( $this->names, function (string $element): bool { return strlen($element) < 5; } ) ); } } $names = new Names([/* ... */]); $shortNames = $names->shortNames();
在集合的转换上使用方法的好处就是获得了一个名称。这使你能够向看起来相当复杂的array_filter()
调用添加一个简短而有意义的标签。
使用自定义集合类来解耦客户端
如果一个客户端使用特定的数组并循环,从选定的元素中取出一段数据,并对该数据进行处理,那么该客户端就与所有涉及的类型紧密耦合: 数组本身、数组中元素的类型、它从所选元素中检索的值的类型、选择器方法的类型,等等。这种深度耦合的问题是,在不破坏依赖于它们的客户端的情况下,很难更改所涉及类型的任何内容。因此,在这种情况下,你也可以将数组包装在一个自定义 的集合类中,让它一次性给出正确的答案,在内部进行必要的计算,让客户端与集合更加松散地耦合。
$lines = []; $sum = 0; foreach ($lines as $line) { if ($line->isComment()) { continue; } $sum += $line->quantity(); } // Turned into a custom collection class: final class Lines { public function totalQuantity(): int { $sum = 0; foreach ($lines as $line) { if ($line->isComment()) { continue; } $sum += $line->quantity(); } return $sum; } }
自定义集合类的一些规则
让我们看看在使用自定义集合类时应用的一些规则。
让它们不可变
对集合实例的现有引用在运行某种转换时不应受到影响。因此,任何执行转换的方法都应该返回类的一个新实例,就像我们在上面的例子中看到的那样:
final class Names { /** * @var array<string> */ private array $names; public function __construct(array $names) { Assert::that()->allIsString($names); $this->names = $names; } public function shortNames(): self { return new self( /* ... */ ); } }
当然,如果要映射内部数组,则可能要映射到另一种类型的集合或简单数组。与往常一样,请确保提供适当的返回类型。
只提供实际客户需要和使用的行为
你不必扩展泛型集合库类,也不必自己在每个自定义集合类上实现泛型筛选器、映射和缩减方法,只实现真正需要的。如果某个方法在某一时刻不被使用,那么就删除它。
使用 IteratorAggregate 和 ArrayIterator 来支持迭代
如果你使用 PHP,不用实现所有的Iterator
接口的方法(并保持一个内部指针,等等),只是实现IteratorAggregate
接口,让它返回一个ArrayIterator
实例基于内部数组:
final class Names implements IteratorAggregate { /** * @var array<string> */ private array $names; public function __construct(array $names) { Assert::that()->allIsString($names); $this->names = $names; } public function getIterator(): Iterator { return new ArrayIterator($this->names); } } $names = new Names([/* ... */]); foreach ($names as $name) { // ... }
权衡考虑
为你的自定义集合类编写更多代码的好处是使客户端更容易地使用该集合(而不是仅仅使用一个数组)。如果客户端代码变得更容易理解,如果集合提供了有用的行为,那么维护自定义集合类的额外成本就是合理的。但是,因为使用动态数组非常容易(主要是因为你不必写出所涉及的类型),所以我不经常介绍自己的集合类。尽管如此,我知道有些人是它们的伟大支持者,所以我将确保继续寻找潜在的用例。
推荐教程:《PHP》
以上がPHP の配列仕様とカスタム コレクションの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。
