Peringatan Kami telah memutuskan untuk berhenti mempertahankan paket ini.
Pertimbangkan untuk bermigrasi ke spatie/laravel-data atau cuyz/valinor.
Jangan ragu untuk membagi kode kami dan menyesuaikannya dengan kebutuhan Anda.
Anda dapat menginstal paket melalui composer:
komposer memerlukan spatie/objek transfer data
Catatan : v3 paket ini hanya mendukung php:^8.0
. Jika Anda mencari versi yang lebih lama, lihat v2.
Kami menginvestasikan banyak sumber daya untuk menciptakan paket sumber terbuka terbaik di kelasnya. Anda dapat mendukung kami dengan membeli salah satu produk berbayar kami.
Kami sangat menghargai Anda mengirimi kami kartu pos dari kota asal Anda, yang menyebutkan paket kami mana yang Anda gunakan. Anda akan menemukan alamat kami di halaman kontak kami. Kami mempublikasikan semua kartu pos yang diterima di dinding kartu pos virtual kami.
Tujuan dari paket ini adalah membuat pembuatan objek dari array data (berseri) semudah mungkin. Berikut tampilan DTO:
gunakan SpatieDataTransferObjectAttributesMapFrom; gunakan SpatieDataTransferObjectDataTransferObject; kelas MyDTO memperluas DataTransferObject {publik OtherDTO $otherDTO; publik OtherDTOCollection $collection; #[CastWith(ComplexObjectCaster::class)]objek Kompleks publik $objek kompleks; publik ComplexObjectWithCast $complexObjectWithCast; #[NomorBetween(1, 100)]publik ke dalam $a; #[MapFrom('address.city')]string publik $kota; }
Anda dapat membuat DTO ini seperti ini:
$dto = MyDTO baru( sebuah: 5, koleksi: [ ['id' => 1], ['id' => 2], ['id' => 3], ], objek kompleks: ['nama' => 'tes', ], complexObjectWithCast: ['nama' => 'tes', ], otherDTO: ['id' => 5], );
Mari kita bahas semua kemungkinan satu per satu.
Membangun DTO dapat dilakukan dengan argumen bernama. Dimungkinkan juga untuk tetap menggunakan notasi array lama. Contoh ini setara dengan contoh di atas.
$dto = baru MyDTO(['a' => 5,'koleksi' => [ ['id' => 1], ['id' => 2], ['id' => 3], ],'objek kompleks' => ['nama' => 'uji', ],'complexObjectWithCast' => ['nama' => 'uji', ],'otherDTO' => ['id' => 5], ]);
Jika DTO mempunyai properti yang merupakan DTO lain atau kumpulan DTO, paket akan menangani transmisi array data secara otomatis ke DTO tersebut:
$dto = MyDTO baru( koleksi: [ // Ini akan menjadi objek kelas OtherDTOCollection['id' => 1], ['id' => 2], // Setiap item akan menjadi turunan dari OtherDTO['id' => 3], ], otherDTO: ['id' => 5], // Data ini akan dikirim ke OtherDTO);
Anda dapat membangun kelas kastor Anda sendiri, yang akan mengambil masukan apa pun yang diberikan, dan akan memberikan masukan tersebut ke hasil yang diinginkan.
Lihatlah ComplexObject
:
kelas Objek Kompleks {string publik $nama; }
Dan kastornya ComplexObjectCaster
:
gunakan SpatieDataTransferObjectCaster; kelas ComplexObjectCaster mengimplementasikan Caster {/** * @param array|nilai $campuran * * @return campuran */pemeran fungsi publik(nilai $campuran): ComplexObject{return new ComplexObject( nama: $nilai['nama'] ); } }
Daripada menentukan kastor mana yang harus digunakan untuk setiap properti, Anda juga dapat menentukan kastor tersebut pada kelas target itu sendiri:
kelas MyDTO memperluas DataTransferObject {public ComplexObjectWithCast $complexObjectWithCast; }
#[CastWith(ComplexObjectWithCastCaster::class)]kelas ComplexObjectWithCast {string publik $nama; }
Dimungkinkan untuk menentukan kastor default pada kelas DTO itu sendiri. Kastor ini akan digunakan setiap kali properti dengan tipe tertentu ditemui dalam kelas DTO.
#[ DefaultCast(DateTimeImmutable::kelas, DateTimeImmutableCaster::kelas), DefaultCast(MyEnum::kelas, EnumCaster::kelas), ]kelas abstrak BaseDataTransferObject memperluas DataTransferObject {publik MyEnum $status; // EnumCaster akan digunakan public DateTimeImmutable $date; // DateTimeImmutableCaster akan digunakan}
Setiap kastor dapat memberikan argumen khusus, implementasi ArrayCaster
bawaan adalah contoh yang baik tentang bagaimana argumen ini dapat digunakan.
Menggunakan argumen bernama saat meneruskan masukan ke kastor Anda akan membantu membuat kode Anda lebih jelas, tetapi hal itu tidak diperlukan.
Misalnya:
/** @var SpatieDataTransferObjectTestsFoo[] */#[CastWith(ArrayCaster::class, itemType: Foo::class)]array publik $collectionWithNamedArguments; /** @var SpatieDataTransferObjectTestsFoo[] */#[CastWith(ArrayCaster::class, Foo::class)]array publik $collectionWithoutNamedArguments;
Perhatikan bahwa argumen pertama yang diteruskan ke konstruktor kastor selalu berupa array dengan tipe nilai yang dilemparkan. Semua argumen lainnya akan diteruskan sebagai argumen tambahan di atribut CastWith
.
Paket ini tidak menawarkan fungsionalitas validasi spesifik apa pun, namun memberi Anda cara untuk membuat atribut validasi Anda sendiri. Misalnya, NumberBetween
adalah atribut validasi yang diterapkan pengguna:
kelas MyDTO memperluas DataTransferObject { #[NomorBetween(1, 100)]publik ke dalam $a; }
Ini berfungsi seperti ini di bawah tenda:
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]kelas NumberBetween mengimplementasikan Validator {fungsi publik __konstruksi(int pribadi $min, int pribadi $max) { }validasi fungsi publik(nilai $campuran): ValidationResult{if ($value < $this->min) {return ValidationResult::invalid("Nilai harus lebih besar atau sama dengan {$this->min}"); }if ($value > $this->max) {return ValidationResult::invalid("Nilai harus kurang dari atau sama dengan {$this->max}"); }kembalikan Hasil Validasi::valid(); } }
Anda dapat memetakan properti DTO dari properti sumber dengan nama berbeda menggunakan atribut #[MapFrom]
.
Ia bekerja dengan nama properti notasi "titik" atau indeks.
kelas PostDTO memperluas DataTransferObject { #[MapFrom('postTitle')]string publik $title; #[MapFrom('user.name')]string publik $penulis; }$dto = new PostDTO(['postTitle' => 'Halo dunia','pengguna' => ['nama' => 'John Doe'] ]);
kelas UserDTO memperluas DataTransferObject { #[MapFrom(0)]string publik $namadepan; #[MapFrom(1)]string publik $lastName; }$dto = PenggunaDTO baru(['John', 'Doe']);
Terkadang Anda juga ingin memetakannya selama transformasi ke Array. Kasus penggunaan yang umum adalah transformasi dari kasus unta ke kasus ular. Untuk itu Anda dapat menggunakan atribut #[MapTo]
.
kelas UserDTO memperluas DataTransferObject { #[PetaDari(0)] #[MapTo('first_name')]string publik $firstName; #[PetaDari(1)] #[MapTo('last_name')]string publik $lastName; }$dto = PenggunaDTO baru(['John', 'Doe']);$dto->toArray() // ['first_name' => 'John', 'last_name'=> 'Doe'];$dto- >hanya('nama_depan')->toArray() // ['nama_depan' => 'John'];
Versi sebelumnya dari paket ini menambahkan kelas FlexibleDataTransferObject
yang memungkinkan Anda mengabaikan properti yang tidak ada di DTO. Perilaku ini telah diubah, semua DTO sekarang fleksibel secara default, namun Anda dapat membuatnya ketat dengan menggunakan atribut #[Strict]
:
kelas NonStrictDuntuk memperluas DataTransferObject {string publik $nama; }// Ini berhasil, NonStrictDto( nama: 'nama', tidak diketahui: 'tidak diketahui');
gunakan SpatieDataTransferObjectAttributesStrict; #[Ketat]kelas StrictDuntuk memperluas DataTransferObject {string publik $nama; }// Ini memunculkan pengecualian SpatieDataTransferObjectExceptionsUnknownPropertiesnew StrictDto( nama: 'nama', tidak diketahui: 'tidak diketahui');
Ada juga beberapa fungsi pembantu yang disediakan untuk bekerja dengan beberapa properti sekaligus.
$postData->semua();$postData->hanya('judul', 'tubuh') ->keArray(); $postData->kecuali('penulis') ->keArray();
Perhatikan bahwa all()
hanya akan mengembalikan semua properti, sementara toArray()
akan melemparkan DTO yang disarangkan ke array juga.
Anda dapat merangkai metode except()
dan only()
:
$postData->kecuali('judul') ->kecuali('tubuh') ->keArray();
Penting untuk dicatat bahwa except()
dan only()
tidak dapat diubah, mereka tidak akan mengubah objek transfer data asli.
Paket ini tidak memaksa objek yang tidak dapat diubah karena PHP tidak mendukungnya, namun Anda selalu dianjurkan untuk menjaga DTO Anda tidak dapat diubah. Untuk membantu Anda, ada metode clone
di setiap DTO yang menerima data untuk diganti:
$clone = $asli->clone(lainnya: ['nama' => 'a']);
Perhatikan bahwa tidak ada data di $original
yang diubah.
Versi ini menghapus kelas DataTransferObjectCollection
. Sebagai gantinya, Anda dapat menggunakan kastor sederhana dan kelas koleksi Anda sendiri.
Berikut ini contoh casting kumpulan DTO ke array DTO:
kelas Bar memperluas DataTransferObject {/** @var SpatieDataTransferObjectTestsFoo[] */#[CastWith(FooArrayCaster::class)]array publik $collectionOfFoo; }kelas Foo memperluas DataTransferObject {string publik $nama; }
kelas FooArrayCaster mengimplementasikan Caster {pemeran fungsi publik(nilai $campuran): array{if (! is_array($value)) {throw new Exception("Hanya dapat mentransmisikan array ke Foo"); }kembalikan array_map(fn (array $data) => foo baru(...$data),$nilai); } }
Jika Anda tidak ingin petunjuk pengetikan yang berlebihan, atau ingin fungsionalitas koleksi yang diperluas; Anda dapat membuat kelas koleksi Anda sendiri menggunakan implementasi koleksi apa pun. Dalam contoh ini, kami menggunakan Laravel:
kelas Bar memperluas DataTransferObject { #[CastWith(FooCollectionCaster::class)]public CollectionOfFoo $collectionOfFoo; }kelas Foo memperluas DataTransferObject {string publik $nama; }
gunakan IlluminateSupportCollection;kelas CollectionOfFoo memperluas Koleksi {// Tambahkan tipe pengembalian yang benar di sini agar penganalisis statis dapat mengetahui tipe array yang mana ini public function offsetGet($key): Foo{return parent::offsetGet($key); } }
kelas FooCollectionCaster mengimplementasikan Caster {pemeran fungsi publik(nilai $campuran): CollectionOfFoo{return new CollectionOfFoo(array_map(fn (array $data) => new Foo(...$data),$value)); } }
Untuk array DTO sederhana, atau objek yang mengimplementasikan ArrayAccess
bawaan PHP, pertimbangkan untuk menggunakan ArrayCaster
yang memerlukan penyediaan tipe item:
kelas Bar memperluas DataTransferObject {/** @var SpatieDataTransferObjectTestsFoo[] */#[CastWith(ArrayCaster::class, itemType: Foo::class)]array publik $collectionOfFoo; }
tes komposer
Silakan lihat CHANGELOG untuk informasi lebih lanjut tentang apa yang berubah baru-baru ini.
Silakan lihat KONTRIBUSI untuk rinciannya.
Jika Anda menemukan bug terkait keamanan, silakan kirim email ke [email protected] alih-alih menggunakan pelacak masalah.
Anda bebas menggunakan paket ini, namun jika paket ini masuk ke lingkungan produksi Anda, kami sangat menghargai Anda mengirimi kami kartu pos dari kota asal Anda, yang menyebutkan paket kami mana yang Anda gunakan.
Alamat kami adalah: Spatie, Kruikstraat 22, 2018 Antwerp, Belgia.
Kami mempublikasikan semua kartu pos yang diterima di situs web perusahaan kami.
json2dto: GUI untuk mengonversi objek JSON ke kelas DTO (dengan dukungan bersarang). Juga menyediakan alat CLI untuk penggunaan lokal.
Pabrik Objek Transfer Data: Secara cerdas menghasilkan instance DTO menggunakan konten yang benar untuk properti Anda berdasarkan nama dan jenisnya.
Brent Roose
Semua Kontributor
Kelas Arr
kami berisi fungsi yang disalin dari pembantu Laravels Arr
.
Lisensi MIT (MIT). Silakan lihat File Lisensi untuk informasi lebih lanjut.