警告このパッケージのメンテナンスを終了することにしました。
spatie/laravel-data または cuyz/valinor への移行を検討してください。
自由にコードをフォークしてニーズに合わせて調整してください。
パッケージは、composer 経由でインストールできます。
コンポーザーには spatie/data-transfer-object が必要です
注: このパッケージの v3 はphp:^8.0
のみをサポートします。古いバージョンをお探しの場合は、v2 をチェックしてください。
私たちはクラス最高のオープンソース パッケージの作成に多くのリソースを投資しています。有料製品のいずれかを購入することで、私たちをサポートできます。
当社のどのパッケージを使用しているかについて、故郷から葉書を送っていただき、誠にありがとうございます。当社の住所は、お問い合わせページに記載されています。受け取ったすべてのポストカードをバーチャル ポストカード ウォールに公開します。
このパッケージの目標は、(シリアル化された) データの配列からオブジェクトをできるだけ簡単に構築できるようにすることです。 DTO は次のようになります。
SpatieDataTransferObjectAttributesMapFrom を使用する;SpatieDataTransferObjectDataTransferObject を使用する;クラス MyDTO は DataTransferObject を拡張します {パブリック OtherDTO $otherDTO; public OtherDTOCollection $collection; #[CastWith(ComplexObjectCaster::class)]public ComplexObject $complexObject; public ComplexObjectWithCast $complexObjectWithCast; #[NumberBetween(1, 100)]public int $a; #[MapFrom('address.city')]パブリック文字列 $city; }
この DTO は次のように構築できます。
$dto = 新しい MyDTO( 答え: 5、 コレクション: [ ['id' => 1], ['id' => 2], ['id' => 3], ]、 complexObject: ['名前' => 'テスト', ]、 complexObjectWithCast: ['名前' => 'テスト', ]、 otherDTO: ['id' => 5], );
あらゆる可能性について一つずつ議論していきましょう。
DTO の構築は、名前付き引数を使用して行うことができます。古い配列表記を引き続き使用することも可能です。この例は上記の例と同等です。
$dto = new MyDTO(['a' => 5,'コレクション' => [ ['id' => 1], ['id' => 2], ['id' => 3], ],'complexObject' => ['name' => 'test', ],'complexObjectWithCast' => ['名前' => 'テスト', ],'otherDTO' => ['id' => 5], ]);
DTO に別の DTO または DTO コレクションのプロパティがある場合、パッケージはデータの配列をそれらの DTO に自動的にキャストします。
$dto = 新しい MyDTO( collection: [ // これはクラス OtherDTOCollection['id' => 1] のオブジェクトになります。 ['id' => 2], // 各項目は OtherDTO のインスタンスになります['id' => 3], ]、 otherDTO: ['id' => 5], // このデータは OtherDTO にキャストされます);
与えられた入力をすべて受け取り、その入力を目的の結果にキャストする独自のキャスター クラスを構築できます。
ComplexObject
を見てください。
クラスComplexObject {パブリック文字列 $name; }
そしてそのキャスターComplexObjectCaster
:
SpatieDataTransferObjectCaster を使用する;ComplexObjectCaster クラスが Caster を実装する {/** * @param array|mixed $value * * @returnmixed */public function Cast(mixed $value): ComplexObject{return new ComplexObject( 名前: $value['名前'] ); } }
各プロパティにどのキャスターを使用するかを指定する代わりに、ターゲット クラス自体にそのキャスターを定義することもできます。
クラス MyDTO は DataTransferObject を拡張します {パブリック ComplexObjectWithCast $complexObjectWithCast; }
#[CastWith(ComplexObjectWithCastCaster::class)]クラス ComplexObjectWithCast {パブリック文字列 $name; }
DTO クラス自体にデフォルトのキャスターを定義することができます。これらのキャスターは、DTO クラス内で特定のタイプのプロパティが見つかったときに必ず使用されます。
#[ DefaultCast(DateTimeImmutable::class, DateTimeImmutableCaster::class), DefaultCast(MyEnum::class, EnumCaster::class), ]抽象クラス BaseDataTransferObject は DataTransferObject を拡張します {パブリック MyEnum $status; // EnumCaster が使用されますpublic DateTimeImmutable $date; // DateTimeImmutableCaster が使用されます}
任意のキャスターにカスタム引数を渡すことができます。組み込みのArrayCaster
実装は、これがどのように使用されるかを示す良い例です。
入力をキャスターに渡すときに名前付き引数を使用すると、コードがより明確になりますが、必須ではありません。
例えば:
/** @var SpatieDataTransferObjectTestsFoo[] */#[CastWith(ArrayCaster::class, itemType: Foo::class)]public array $collectionWithNamedArguments; /** @var SpatieDataTransferObjectTestsFoo[] */#[CastWith(ArrayCaster::class, Foo::class)]パブリック配列 $collectionWithoutNamedArguments;
キャスター コンストラクターに渡される最初の引数は、常にキャストされる値の型を持つ配列であることに注意してください。他のすべての引数は、 CastWith
属性の追加引数として渡されるものになります。
このパッケージは特定の検証機能を提供しませんが、独自の検証属性を構築する方法を提供します。たとえば、 NumberBetween
はユーザー実装の検証属性です。
クラス MyDTO は DataTransferObject を拡張します { #[NumberBetween(1, 100)]public int $a; }
内部では次のように動作します。
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]クラス NumberBetween は Validator を実装します {パブリック関数 __construct(private int $min,private int $max) { }public function validate(mixed $value): ValidationResult{if ($value < $this->min) {return ValidationResult::invalid("値は {$this->min} 以上である必要があります"); }if ($value > $this->max) {return ValidationResult::invalid("値は {$this->max} 以下である必要があります"); ValidationResult::valid() を返します。 } }
#[MapFrom]
属性を使用すると、ソース プロパティから DTO プロパティを別の名前でマップできます。
これは、「ドット」表記のプロパティ名またはインデックスで機能します。
クラス PostDTO は DataTransferObject を拡張します { #[MapFrom('postTitle')]パブリック文字列 $title; #[MapFrom('user.name')]パブリック文字列 $author; }$dto = new PostDTO(['postTitle' => 'Hello world','user' => ['name' => 'John Doe'] ]);
クラス UserDTO は DataTransferObject を拡張します { #[MapFrom(0)]パブリック文字列 $firstName; #[MapFrom(1)]パブリック文字列 $lastName; }$dto = 新しい UserDTO(['John', 'Doe']);
場合によっては、配列への変換中にそれらをマップすることもできます。典型的なユースケースは、キャメル ケースからスネーク ケースへの変換です。そのためには#[MapTo]
属性を使用できます。
クラス UserDTO は DataTransferObject を拡張します { #[地図から(0)] #[MapTo('first_name')]パブリック文字列 $firstName; #[地図から(1)] #[MapTo('last_name')]パブリック文字列 $lastName; }$dto = new UserDTO(['John', 'Doe']);$dto->toArray() // ['first_name' => 'John', 'last_name'=> 'Doe'];$dto- >only('first_name')->toArray() // ['first_name' => 'John'];
このパッケージの以前のバージョンでは、DTO に存在しないプロパティを無視できるFlexibleDataTransferObject
クラスが追加されました。この動作は変更されており、すべての DTO はデフォルトで柔軟になっていますが、 #[Strict]
属性を使用して DTO を厳密にすることができます。
クラス NonStrictDto は DataTransferObject を拡張します {パブリック文字列 $name; }// これは機能しますnew NonStrictDto( 名前: '名前'、 不明:「不明」);
SpatieDataTransferObjectAttributesStrict を使用します。 #[Strict]クラス StrictD で DataTransferObject を拡張します {パブリック文字列 $name; }// これにより、SpatieDataTransferObjectExceptionsUnknownProperties 例外がスローされますnew StrictDto( 名前: '名前'、 不明:「不明」);
複数のプロパティを一度に操作するために提供されるヘルパー関数もいくつかあります。
$postData->all();$postData->only('タイトル', '本文') ->toArray(); $postData->例外('作成者') ->toArray();
all()
単にすべてのプロパティを返すのに対し、 toArray()
ネストされた DTO も配列にキャストすることに注意してください。
except()
とonly()
メソッドを連鎖させることができます。
$postData->Except('タイトル') ->以外('本体') ->toArray();
except()
とonly()
不変であり、元のデータ転送オブジェクトを変更しないことに注意することが重要です。
PHP は不変オブジェクトをサポートしていないため、このパッケージは不変オブジェクトを強制しませんが、DTO を不変に保つことを常にお勧めします。これを助けるために、オーバーライドするデータを受け入れるclone
メソッドがすべての DTO にあります。
$clone = $original->clone(other: ['name' => 'a']);
$original
のデータは変更されないことに注意してください。
このバージョンでは、 DataTransferObjectCollection
クラスが削除されています。代わりに、単純なキャスターと独自のコレクション クラスを使用できます。
DTO のコレクションを DTO の配列にキャストする例を次に示します。
クラス Bar は DataTransferObject を拡張します {/** @var SpatieDataTransferObjectTestsFoo[] */#[CastWith(FooArrayCaster::class)]パブリック配列 $collectionOfFoo; }クラス Foo は DataTransferObject を拡張します {パブリック文字列 $name; }
クラス FooArrayCaster は Caster を実装します {public function Cast(mixed $value): array{if (! is_array($value)) {throw new Exception("配列は Foo にのみキャストできます"); }return array_map(fn (array $data) => new Foo(...$data),$value); } }
冗長なタイプヒントが不要な場合、または拡張コレクション機能が必要な場合。任意のコレクション実装を使用して独自のコレクション クラスを作成できます。この例では、Laravel のものを使用します。
クラス Bar は DataTransferObject を拡張します { #[CastWith(FooCollectionCaster::class)]public CollectionOfFoo $collectionOfFoo; }クラス Foo は DataTransferObject を拡張します {パブリック文字列 $name; }
IlluminateSupportCollection を使用する;クラス CollectionOfFoo は Collection を拡張します {// 静的アナライザーがパブリック関数 offsetGet($key): Foo{returnparent::offsetGet($key); の型を知るために、ここに正しい戻り値の型を追加します。 } }
クラス FooCollectionCaster は Caster を実装します {パブリック関数 Cast(mixed $value): CollectionOfFoo{return new CollectionOfFoo(array_map(fn (array $data) => new Foo(...$data),$value)); } }
DTO の単純な配列、または PHP の組み込みArrayAccess
実装するオブジェクトの場合は、項目タイプを指定する必要があるArrayCaster
の使用を検討してください。
クラス Bar は DataTransferObject を拡張します {/** @var SpatieDataTransferObjectTestsFoo[] */#[CastWith(ArrayCaster::class, itemType: Foo::class)]パブリック配列 $collectionOfFoo; }
作曲家テスト
最近の変更点の詳細については、CHANGELOG を参照してください。
詳細については、「貢献」を参照してください。
セキュリティに関するバグを見つけた場合は、問題トラッカーを使用する代わりに [email protected] にメールを送信してください。
このパッケージを自由に使用できますが、実稼働環境に届いた場合は、どのパッケージを使用しているかを記載した葉書を故郷から送っていただければ幸いです。
私たちの住所は、Spatie, Kruikstraat 22, 2018 Antwerp, Belgiumです。
いただいたはがきはすべて当社ホームページに掲載しております。
json2dto: JSON オブジェクトを DTO クラスに変換する GUI (ネストのサポートあり)。ローカルで使用するための CLI ツールも提供します。
データ転送オブジェクト ファクトリ: 名前とタイプに基づいてプロパティの正しいコンテンツを使用して DTO インスタンスをインテリジェントに生成します。
ブレント・ルース
すべての貢献者
Arr
クラスには、Laravels Arr
ヘルパーからコピーされた関数が含まれています。
MIT ライセンス (MIT)。詳細については、ライセンス ファイルを参照してください。