경고 우리는 이 패키지의 유지 관리를 중단하기로 결정했습니다.
spatie/laravel-data 또는 cuyz/valinor로 마이그레이션하는 것을 고려해보세요.
우리의 코드를 자유롭게 포크하고 필요에 맞게 조정하세요.
작곡가를 통해 패키지를 설치할 수 있습니다.
작곡가에게는 spatie/data-transfer-object가 필요합니다.
참고 : 이 패키지의 v3은 php:^8.0
만 지원합니다. 이전 버전을 찾고 있다면 v2를 확인하세요.
우리는 동급 최고의 오픈 소스 패키지를 만드는 데 많은 리소스를 투자합니다. 유료 제품 중 하나를 구매하여 우리를 지원할 수 있습니다.
귀하가 사용하고 있는 당사 패키지를 언급하면서 귀하의 고향에서 엽서를 보내주셔서 진심으로 감사드립니다. 연락처 페이지에서 주소를 확인하실 수 있습니다. 우리는 수신된 모든 엽서를 가상 엽서 월에 게시합니다.
이 패키지의 목표는 (직렬화된) 데이터 배열에서 객체를 생성하는 것을 최대한 쉽게 만드는 것입니다. DTO의 모습은 다음과 같습니다.
SpatieDataTransferObjectAttributesMapFrom 사용; SpatieDataTransferObjectDataTransferObject 사용; 클래스 MyDTO는 DataTransferObject를 확장합니다. {공용 기타DTO $otherDTO; 공개 OtherDTOCollection $collection; #[CastWith(ComplexObjectCaster::class)]public ComplexObject $complexObject; 공개 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' => ['이름' => '테스트', ],'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 {공개 문자열 $이름; }
그리고 그 캐스터인 ComplexObjectCaster
는 다음과 같습니다.
SpatieDataTransferObjectCaster를 사용하고 ComplexObjectCaster 클래스는 Caster를 구현합니다. {/** * @param array|mixed $value * * @return Mixed */public 함수 캐스트(mixed $value): ComplexObject{return new ComplexObject( 이름: $value['이름'] ); } }
각 속성에 어떤 캐스터를 사용해야 하는지 지정하는 대신 대상 클래스 자체에 해당 캐스터를 정의할 수도 있습니다.
MyDTO 클래스는 DataTransferObject를 확장합니다. {공용 ComplexObjectWithCast $complexObjectWithCast; }
#[CastWith(ComplexObjectWithCastCaster::class)]class ComplexObjectWithCast {공개 문자열 $이름; }
DTO 클래스 자체에 기본 캐스터를 정의하는 것이 가능합니다. 이러한 캐스터는 DTO 클래스 내에서 특정 유형의 속성이 발견될 때마다 사용됩니다.
#[ DefaultCast(DateTimeImmutable::class, DateTimeImmutableCaster::class), DefaultCast(MyEnum::class, EnumCaster::class), ]추상 클래스 BaseDataTransferObject는 DataTransferObject를 확장합니다. {공개 MyEnum $상태; // EnumCaster가 사용됩니다.public DateTimeImmutable $date; // DateTimeImmutableCaster가 사용됩니다.}
모든 캐스터는 사용자 정의 인수를 전달할 수 있으며, 내장된 ArrayCaster
구현은 이것이 어떻게 사용될 수 있는지 보여주는 좋은 예입니다.
입력을 캐스터에 전달할 때 명명된 인수를 사용하면 코드를 더 명확하게 만드는 데 도움이 되지만 필수는 아닙니다.
예를 들어:
/** @var SpatieDataTransferObjectTestsFoo[] */#[CastWith(ArrayCaster::class, itemType: Foo::class)]공용 배열 $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)]class NumberBetween은 유효성 검사기를 구현합니다. {공용 함수 __construct(private int $min,private int $max) { }public function verify(mixed $value): ValidationResult{if ($value < $this->min) {return ValidationResult::invalid("값은 {$this->min}보다 크거나 같아야 합니다."); }if ($value > $this->max) {return ValidationResult::invalid("값은 {$this->max}보다 작거나 같아야 합니다."); }return 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 = new UserDTO(['John', 'Doe']);
때로는 배열로 변환하는 동안 이를 매핑하고 싶을 수도 있습니다. 일반적인 사용 사례는 낙타 케이스에서 뱀 케이스로 변환하는 것입니다. 이를 위해 #[MapTo]
속성을 사용할 수 있습니다.
UserDTO 클래스는 DataTransferObject를 확장합니다. { #[MapFrom(0)] #[MapTo('first_name')]공개 문자열 $firstName; #[MapFrom(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]
속성을 사용하여 엄격하게 만들 수 있습니다.
NonStrictDto 클래스는 DataTransferObject를 확장합니다. {공개 문자열 $이름; }// 이것은 새로운 NonStrictDto( 이름: '이름', 알 수 없음: '알 수 없음');
SpatieDataTransferObjectAttributesStrict를 사용하십시오. #[Strict]class StrictDto는 DataTransferObject를 확장합니다. {공개 문자열 $이름; }// 이 경우 SpatieDataTransferObjectExceptionsUnknownProperties 예외가 발생합니다new StrictDto( 이름: '이름', 알 수 없음: '알 수 없음');
동시에 여러 속성을 작업하기 위해 제공되는 몇 가지 도우미 함수도 있습니다.
$postData->all();$postData->only('제목', '본문') ->toArray(); $postData->제외('저자') ->toArray();
all()
단순히 모든 속성을 반환하는 반면 toArray()
중첩된 DTO도 배열로 변환합니다.
except()
및 only()
메서드를 연결할 수 있습니다.
$postData->제외('제목') ->제외('본문') ->toArray();
except()
및 only()
는 변경할 수 없으며 원래 데이터 전송 객체를 변경하지 않는다는 점에 유의하는 것이 중요합니다.
이 패키지는 PHP가 불변 개체를 지원하지 않기 때문에 이를 강제로 적용하지 않지만 항상 DTO를 불변으로 유지하는 것이 좋습니다. 도움을 주기 위해 모든 DTO에는 재정의할 데이터를 허용하는 clone
메서드가 있습니다.
$clone = $original->clone(기타: ['이름' => 'a']);
$original
의 데이터는 변경되지 않습니다.
이 버전에서는 DataTransferObjectCollection
클래스가 제거되었습니다. 대신 간단한 캐스터와 자신만의 컬렉션 클래스를 사용할 수 있습니다.
다음은 DTO 컬렉션을 DTO 배열로 캐스팅하는 예입니다.
클래스 Bar는 DataTransferObject를 확장합니다. {/** @var SpatieDataTransferObjectTestsFoo[] */#[CastWith(FooArrayCaster::class)]공개 배열 $collectionOfFoo; } Foo 클래스는 DataTransferObject를 확장합니다. {공개 문자열 $이름; }
FooArrayCaster 클래스는 Caster를 구현합니다. {public function cast(mixed $value): array{if (! is_array($value)) {throw new Exception("Foo에만 배열을 캐스팅할 수 있습니다."); }return array_map(fn (배열 $data) => new Foo(...$data),$value); } }
중복된 유형 힌트를 원하지 않거나 확장된 컬렉션 기능을 원하는 경우; 컬렉션 구현을 사용하여 자신만의 컬렉션 클래스를 만들 수 있습니다. 이 예에서는 Laravel의 다음을 사용합니다.
클래스 Bar는 DataTransferObject를 확장합니다. { #[CastWith(FooCollectionCaster::class)]public CollectionOfFoo $collectionOfFoo; } Foo 클래스는 DataTransferObject를 확장합니다. {공개 문자열 $이름; }
IlluminateSupportCollection 사용;class CollectionOfFoo는 Collection을 확장합니다. {// 정적 분석기가 이것이 어떤 배열 유형인지 알 수 있도록 여기에 올바른 반환 유형을 추가하세요. 공개 함수 offsetGet($key): Foo{return parent::offsetGet($key); } }
FooCollectionCaster 클래스는 Caster를 구현합니다. {공용 함수 캐스트(혼합 $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; }
작곡가 테스트
최근 변경된 사항에 대한 자세한 내용은 변경 로그를 참조하세요.
자세한 내용은 CONTRIBUTING을 참조하세요.
보안 관련 버그를 발견한 경우 이슈 트래커를 사용하는 대신 [email protected]로 메일을 보내주세요.
이 패키지를 무료로 사용할 수 있지만, 귀하의 프로덕션 환경에 적용된다면 귀하가 사용하고 있는 패키지를 언급하면서 고향에서 엽서를 보내주시면 감사하겠습니다.
주소는 Spatie, Kruikstraat 22, 2018 Antwerp, Belgium입니다.
우리는 받은 모든 엽서를 회사 웹사이트에 게시합니다.
json2dto: JSON 개체를 DTO 클래스로 변환하는 GUI입니다(중첩 지원 포함). 또한 로컬 사용을 위한 CLI 도구를 제공합니다.
데이터 전송 개체 팩토리: 이름과 유형을 기반으로 속성에 대한 올바른 콘텐츠를 사용하여 DTO 인스턴스를 지능적으로 생성합니다.
브렌트 루즈
모든 기여자
Arr
클래스에는 Laravels Arr
도우미에서 복사한 함수가 포함되어 있습니다.
MIT 라이센스(MIT). 자세한 내용은 라이센스 파일을 참조하십시오.