คำเตือน เราได้ตัดสินใจหยุดดูแลรักษาแพ็คเกจนี้
พิจารณาย้ายไปยัง spatie/laravel-data หรือ cuyz/valinor
อย่าลังเลที่จะแยกโค้ดของเราและปรับให้เข้ากับความต้องการของคุณ
คุณสามารถติดตั้งแพ็คเกจผ่านทางผู้แต่ง:
ผู้แต่งต้องการ spatie/data-transfer-object
หมายเหตุ : v3 ของแพ็คเกจนี้รองรับเฉพาะ php:^8.0 เท่านั้น หากคุณกำลังมองหาเวอร์ชันเก่า ลองดูเวอร์ชัน 2
เราลงทุนทรัพยากรจำนวนมากเพื่อสร้างแพ็คเกจโอเพ่นซอร์สที่ดีที่สุดในระดับเดียวกัน คุณสามารถสนับสนุนเราได้โดยการซื้อหนึ่งในผลิตภัณฑ์ที่ต้องชำระเงินของเรา
เราขอขอบคุณอย่างยิ่งที่คุณส่งโปสการ์ดจากบ้านเกิดของคุณถึงเรา โดยระบุว่าคุณใช้แพ็คเกจใดของเรา คุณจะพบที่อยู่ของเราในหน้าติดต่อของเรา เราเผยแพร่โปสการ์ดที่ได้รับทั้งหมดบนวอลล์โปสการ์ดเสมือนของเรา
เป้าหมายของแพ็คเกจนี้คือการสร้างออบเจ็กต์จากอาร์เรย์ของข้อมูล (แบบอนุกรม) ง่ายที่สุด DTO มีลักษณะดังนี้:
ใช้ SpatieDataTransferObjectAttributesMapFrom; ใช้ SpatieDataTransferObjectDataTransferObject; คลาส MyDTO ขยาย DataTransferObject
{สาธารณะ OtherDTO $otherDTO; สาธารณะ OtherDTOCollection $collection;
#[CastWith(ComplexObjectCaster::class)]สาธารณะ 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: ['ชื่อ' => 'ทดสอบ',
-
อื่นๆDTO: ['id' => 5],
-เรามาหารือเกี่ยวกับความเป็นไปได้ทั้งหมดทีละรายการ
การสร้าง DTO สามารถทำได้โดยใช้อาร์กิวเมนต์ที่มีชื่อ คุณยังสามารถใช้สัญลักษณ์อาร์เรย์แบบเก่าได้ ตัวอย่างนี้เทียบเท่ากับตัวอย่างข้างต้น
$dto = ใหม่ MyDTO(['a' => 5,'collection' => [
['id' => 1],
['id' => 2],
['id' => 3],
],'complexObject' => ['ชื่อ' => 'ทดสอบ',
],'complexObjectWithCast' => ['ชื่อ' => 'ทดสอบ',
],'otherDTO' => ['id' => 5],
-หาก DTO มีคุณสมบัติที่เป็น DTO อื่นหรือคอลเลกชัน DTO แพ็คเกจจะดูแลการส่งอาร์เรย์ของข้อมูลไปยัง DTO เหล่านั้นโดยอัตโนมัติ:
$dto = MyDTO ใหม่(
คอลเลกชัน: [ // สิ่งนี้จะกลายเป็นวัตถุของคลาส OtherDTOCollection['id' => 1],
['id' => 2], // แต่ละรายการจะเป็นอินสแตนซ์ของ OtherDTO['id' => 3],
-
otherDTO: ['id' => 5], // ข้อมูลนี้จะถูกส่งไปยัง OtherDTO);คุณสามารถสร้างคลาสแคสเตอร์ของคุณเองได้ ซึ่งจะนำอินพุตใดก็ตามที่ได้รับมา และจะแปลงอินพุตนั้นให้เป็นผลลัพธ์ที่ต้องการ
ดู ComplexObject :
คลาส ComplexObject
{สตริงสาธารณะ $name;
- และลูกล้อของมัน ComplexObjectCaster :
ใช้ SpatieDataTransferObjectCaster; คลาส ComplexObjectCaster ใช้งาน Caster
{/** * @param array|mixed $value * * @return mix */public function cast (mixed $value): ComplexObject{return new ComplexObject(
ชื่อ: $value['ชื่อ']
-
-
-แทนที่จะระบุว่าควรใช้ลูกล้อใดสำหรับแต่ละคุณสมบัติ คุณยังสามารถกำหนดลูกล้อนั้นในคลาสเป้าหมายได้:
คลาส MyDTO ขยาย DataTransferObject
{สาธารณะ ComplexObjectWithCast $complexObjectWithCast;
- #[CastWith(ComplexObjectWithCastCaster::class)]คลาส ComplexObjectWithCast
{สตริงสาธารณะ $name;
-เป็นไปได้ที่จะกำหนดลูกล้อเริ่มต้นในคลาส DTO เอง ลูกล้อเหล่านี้จะถูกนำมาใช้เมื่อใดก็ตามที่พบคุณสมบัติตามประเภทที่กำหนดภายในคลาส DTO
-
DefaultCast(DateTimeImmutable::คลาส, DateTimeImmutableCaster::คลาส),
DefaultCast(MyEnum::คลาส, EnumCaster::คลาส),
]คลาสนามธรรม BaseDataTransferObject ขยาย DataTransferObject
{สถานะ $MyEnum สาธารณะ; // EnumCaster จะถูกใช้งาน 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;
-มันทำงานเช่นนี้ภายใต้ประทุน:
#[แอตทริบิวต์(แอตทริบิวต์::TARGET_PROPERTY | คุณลักษณะ::IS_REPEATABLE)]คลาส NumberBetween ใช้ Validator
{ ฟังก์ชั่นสาธารณะ __ สร้าง (ส่วนตัว int $min, ส่วนตัว int $max) {
}ตรวจสอบฟังก์ชันสาธารณะ (ผสม $value): ValidationResult{if ($value < $this->min) {return ValidationResult::invalid("ค่าควรมากกว่าหรือเท่ากับ {$this->min}");
}if ($value > $this->max) {return ValidationResult::invalid("ค่าควรน้อยกว่าหรือเท่ากับ {$this->max}");
} ส่งคืน ValidationResult::valid();
-
- คุณสามารถแมปคุณสมบัติ DTO จากคุณสมบัติแหล่งที่มาด้วยชื่ออื่นได้โดยใช้แอตทริบิวต์ #[MapFrom]
ใช้งานได้กับชื่อคุณสมบัติสัญลักษณ์ "จุด" หรือดัชนี
คลาส 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']); บางครั้งคุณอาจต้องการแมปพวกมันระหว่างการแปลงเป็น Array กรณีการใช้งานทั่วไปคือการเปลี่ยนจากกรณีอูฐไปเป็นกรณีงู เพื่อที่คุณสามารถใช้แอตทริบิวต์ #[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- >เท่านั้น('first_name')->toArray() // ['first_name' => 'John']; เวอร์ชันก่อนหน้าของแพ็คเกจนี้เพิ่มคลาส FlexibleDataTransferObject ซึ่งอนุญาตให้คุณละเว้นคุณสมบัติที่ไม่มีอยู่ใน DTO ลักษณะการทำงานนี้มีการเปลี่ยนแปลง DTO ทั้งหมดมีความยืดหยุ่นตามค่าเริ่มต้น แต่คุณสามารถทำให้เข้มงวดได้โดยใช้แอตทริบิวต์ #[Strict] :
คลาส NonStrictDto ขยาย DataTransferObject
{สตริงสาธารณะ $name;
}// ใช้งานได้ใหม่ NonStrictDto(
ชื่อ: 'ชื่อ'
ไม่ทราบ: 'ไม่ทราบ'); ใช้ SpatieDataTransferObjectAttributesStrict;
#[Strict]คลาส StrictDto ขยาย DataTransferObject
{สตริงสาธารณะ $name;
}// สิ่งนี้จะพ่น SpatieDataTransferObjectExceptionsUnknownProperties ข้อยกเว้นใหม่ StrictDto(
ชื่อ: 'ชื่อ'
ไม่ทราบ: 'ไม่ทราบ');นอกจากนี้ยังมีฟังก์ชันตัวช่วยบางอย่างสำหรับการทำงานกับคุณสมบัติหลายรายการพร้อมกัน
$postData->all();$postData->only('title', 'body')
->toArray();
$postData->ยกเว้น('ผู้เขียน')
->toArray(); โปรดทราบว่า all() จะส่งกลับคุณสมบัติทั้งหมด ในขณะที่ toArray() จะส่ง DTO ที่ซ้อนกันไปยังอาร์เรย์เช่นกัน
คุณสามารถเชื่อมโยงเมธอด except() และ only() :
$postData->ยกเว้น('ชื่อ')
->ยกเว้น('ร่างกาย')
->toArray(); สิ่งสำคัญคือต้องทราบว่า except() และ only() ที่ไม่เปลี่ยนรูป โดยจะไม่เปลี่ยนอ็อบเจ็กต์การถ่ายโอนข้อมูลดั้งเดิม
แพ็คเกจนี้ไม่บังคับวัตถุที่ไม่เปลี่ยนรูปเนื่องจาก PHP ไม่รองรับ แต่ขอแนะนำให้คุณรักษา DTO ของคุณให้ไม่เปลี่ยนรูปอยู่เสมอ เพื่อช่วยเหลือคุณ มีวิธี clone ในทุก DTO ที่ยอมรับข้อมูลเพื่อแทนที่:
$clone = $Original->Clone(อื่นๆ: ['ชื่อ' => 'a']);
โปรดทราบว่าไม่มีการเปลี่ยนแปลงข้อมูลใน $original
เวอร์ชันนี้จะลบคลาส DataTransferObjectCollection คุณสามารถใช้ล้อธรรมดาและคลาสคอลเลกชันของคุณเองแทนได้
ต่อไปนี้เป็นตัวอย่างของการส่งคอลเล็กชันของ DTO ไปยังอาร์เรย์ของ DTO:
คลาสบาร์ขยาย DataTransferObject
{/** @var SpatieDataTransferObjectTestsFoo[] */#[CastWith(FooArrayCaster::class)]อาร์เรย์สาธารณะ $collectionOfFoo;
}คลาส Foo ขยาย DataTransferObject
{สตริงสาธารณะ $name;
- คลาส FooArrayCaster ใช้ Caster
{ ฟังก์ชั่นสาธารณะหล่อ (ผสม $value): array{if (! is_array($value)) {throw new Exception("สามารถส่งอาร์เรย์ไปที่ Foo เท่านั้น");
}return array_map(fn (array $data) => new Foo(...$data),$value);
-
-หากคุณไม่ต้องการคำใบ้การพิมพ์ที่ซ้ำซ้อน หรือต้องการฟังก์ชันการรวบรวมเพิ่มเติม คุณสามารถสร้างคลาสคอลเลกชั่นของคุณเองโดยใช้การใช้งานคอลเลกชั่นใดก็ได้ ในตัวอย่างนี้ เราใช้ของ Laravel:
คลาสบาร์ขยาย DataTransferObject
-
#[CastWith(FooCollectionCaster::class)]CollectionOfFoo $collectionOfFoo;
}คลาส Foo ขยาย DataTransferObject
{สตริงสาธารณะ $name;
- ใช้ IlluminateSupportCollection;class CollectionOfFoo ขยายคอลเลกชัน
{// เพิ่มประเภทการส่งคืนที่ถูกต้องที่นี่เพื่อให้เครื่องวิเคราะห์คงที่ทราบว่าอาร์เรย์ประเภทใดที่เป็นฟังก์ชันสาธารณะ offsetGet($key): Foo{return parent::offsetGet($key);
-
- คลาส FooCollectionCaster ใช้ Caster
{ ฟังก์ชั่นสาธารณะ (ผสม $value): CollectionOfFoo{return new CollectionOfFoo(array_map(fn (array $data) => new Foo(...$data),$value));
-
- สำหรับอาร์เรย์แบบง่ายของ DTO หรือออบเจ็กต์ที่ใช้ ArrayAccess ในตัวของ PHP ให้พิจารณาใช้ ArrayCaster ซึ่งกำหนดให้ต้องระบุประเภทรายการ:
คลาสบาร์ขยาย DataTransferObject
{/** @var SpatieDataTransferObjectTestsFoo[] */#[CastWith(ArrayCaster::class, itemType: Foo::class)]อาร์เรย์สาธารณะ $collectionOfFoo;
-การทดสอบผู้แต่ง
โปรดดู CHANGELOG สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่เปลี่ยนแปลงเมื่อเร็วๆ นี้
โปรดดูการมีส่วนร่วมเพื่อดูรายละเอียด
หากคุณพบข้อบกพร่องเกี่ยวกับการรักษาความปลอดภัย โปรดส่งอีเมลมาที่ [email protected] แทนการใช้ตัวติดตามปัญหา
คุณสามารถใช้แพ็คเกจนี้ได้อย่างอิสระ แต่หากมันเหมาะกับสภาพแวดล้อมการใช้งานจริงของคุณ เราขอขอบคุณอย่างยิ่งที่คุณส่งโปสการ์ดจากบ้านเกิดของคุณมาให้เรา โดยระบุว่าคุณกำลังใช้แพ็คเกจใดของเรา
ที่อยู่ของเราคือ: Spatie, Kruikstraat 22, 2018 แอนต์เวิร์ป, เบลเยียม
เราเผยแพร่ไปรษณียบัตรที่ได้รับทั้งหมดบนเว็บไซต์ของบริษัทของเรา
json2dto: GUI สำหรับแปลงวัตถุ JSON เป็นคลาส DTO (พร้อมการรองรับการซ้อน) ยังมีเครื่องมือ CLI สำหรับการใช้งานในท้องถิ่น
Data Transfer Object Factory: สร้างอินสแตนซ์ DTO อย่างชาญฉลาดโดยใช้เนื้อหาที่ถูกต้องสำหรับคุณสมบัติของคุณตามชื่อและประเภท
เบรนต์ รูส
ผู้ร่วมให้ข้อมูลทั้งหมด
คลาส Arr ของเรามีฟังก์ชันที่คัดลอกมาจากตัวช่วย Laravels Arr
ใบอนุญาตเอ็มไอที (MIT) โปรดดูไฟล์ใบอนุญาตสำหรับข้อมูลเพิ่มเติม