


pengenalan
DTO ialah objek ringkas yang merangkum atribut data tanpa mengandungi sebarang logik perniagaan. Ia sering digunakan untuk mengagregat data daripada pelbagai sumber ke dalam satu objek, menjadikannya lebih mudah untuk diurus dan dihantar. Dengan menggunakan DTO, pembangun boleh mengurangkan bilangan panggilan kaedah, meningkatkan prestasi dan memudahkan pengendalian data, terutamanya dalam sistem atau API teragih.
Sebagai contoh, kami boleh menggunakan DTO untuk memetakan data yang diterima melalui Permintaan HTTP. DTO tersebut akan menyimpan nilai muatan yang diterima pada harta mereka dan kami boleh menggunakannya dalam aplikasi, contohnya, dengan mencipta objek entiti doktrin yang sedia untuk disimpan ke pangkalan data daripada data yang disimpan dalam DTO. Memandangkan data DTO sudah pun disahkan, ia boleh mengurangkan kebarangkalian menjana ralat semasa pangkalan data berterusan.
Atribut MapQueryString dan MapRequestPayload
Atribut MapQueryString dan MapRequestPayload membolehkan kami masing-masing memetakan rentetan pertanyaan dan parameter muatan yang diterima. Mari lihat contoh kedua-duanya.
Contoh MapQueryString
Mari bayangkan kita mempunyai laluan Symfony yang boleh menerima parameter berikut dalam rentetan pertanyaan:
- dari: Wajib dari tarikh
- kepada: Wajib setakat ini
- umur: Umur pilihan
Berdasarkan parameter di atas, kami ingin memetakannya ke dto berikut:
readonly class QueryInputDto { public function __construct( #[Assert\Datetime(message: 'From must be a valid datetime')] #[Assert\NotBlank(message: 'From date cannot be empty')] public string $from, #[Assert\Datetime(message: 'To must be a valid datetime')] #[Assert\NotBlank(message: 'To date cannot be empty')] public string $to, public ?int $age = null ){} }
Untuk memetakannya, kita hanya perlu menggunakan atribut MapQueryString mengikut cara ini:
#[Route('/my-get-route', name: 'my_route_name', methods: ['GET'])] public function myAction(#[MapQueryString] QueryInputDTO $queryInputDto) { // your code }
Seperti yang anda lihat, apabila symfony mengesan bahawa argumen $queryInputDto telah dibenderakan dengan atribut #[MapQueryString], ia secara automatik memetakan rentetan pertanyaan yang diterima parameter ke dalam argumen itu yang merupakan contoh bagi Kelas QueryInputDTO.
Contoh MapRequestPayload
Dalam kes ini, mari bayangkan kita mempunyai laluan Symfony yang menerima data yang diperlukan untuk mendaftarkan pengguna baharu dalam muatan permintaan JSON. Parameter tersebut adalah seperti berikut:
- nama: wajib
- e-mel: wajib
- tarikh lahir (dob): wajib
Berdasarkan parameter di atas, kami ingin memetakannya ke dto berikut:
readonly class PayloadInputDto { public function __construct( #[Assert\NotBlank(message: 'Name cannot be empty')] public string $name, #[Assert\NotBlank(message: 'Email cannot be empty')] #[Assert\Email(message: 'Email must be a valid email')] public string $email, #[Assert\NotBlank(message: 'From date cannot be empty')] #[Assert\Date(message: 'Dob must be a valid date')] public ?string $dob = null ){} }
Untuk memetakannya, kita hanya perlu menggunakan atribut MapRequestPayload mengikut cara ini:
#[Route('/my-post-route', name: 'my_post_route', methods: ['POST'])] public function myAction(#[MapRequestPayload] PayloadInputDTO $payloadInputDto) { // your code }
Seperti yang telah kita lihat dalam bahagian sebelumnya, apabila symfony mengesan bahawa argumen $payloadInputDto telah dibenderakan dengan atribut #[MapRequestPayload], ia secara automatik memetakan parameter muatan yang diterima ke dalam hujah tersebut iaitu contoh kelas PayloadInputDTO.
MapRequestPayload berfungsi untuk muatan JSON dan muatan berkod url borang.
Mengendalikan ralat pengesahan DTO
Jika pengesahan gagal semasa proses pemetaan (contohnya, e-mel mandatori belum dihantar) Symfony membuang pengecualian 422 Kandungan Tidak Boleh Diproses. Jika anda ingin menangkap jenis pengecualian ini dan mengembalikan ralat pengesahan sebagai, contohnya, json kepada klien, anda boleh membuat pelanggan acara dan terus mendengar acara KernelException.
class KernelSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ KernelEvents::EXCEPTION => 'onException' ]; } public function onException(ExceptionEvent $event): void { $exception = $event->getThrowable(); if($exception instanceof UnprocessableEntityHttpException) { $previous = $exception->getPrevious(); if($previous instanceof ValidationFailedException) { $errors = []; foreach($previous->getViolations() as $violation) { $errors[] = [ 'path' => $violation->getPropertyPath(), 'error' => $violation->getMessage() ]; } $event->setResponse(new JsonResponse($errors)); } } } }
Selepas kaedah onException dicetuskan, ia menyemak sama ada pengecualian acara ialah tika UnprocessableEntityHttpException. Jika ya, ia juga menyemak sama ada ralat yang tidak boleh diproses datang daripada pengesahan yang gagal yang memeriksa sama ada pengecualian sebelumnya ialah contoh kelas ValidationFailedException. Jika ya, ia menyimpan semua ralat pelanggaran dalam tatasusunan (hanya laluan sifat sebagai kunci dan mesej pelanggaran sebagai ralat), mencipta respons JSON daripada ralat ini dan menetapkan respons baharu kepada acara tersebut.
Imej berikut menunjukkan respons JSON untuk permintaan yang gagal kerana e-mel belum dihantar:
@baseUrl = http://127.0.0.1:8000 POST {{baseUrl}}/my-post-route Content-Type: application/json { "name" : "Peter Parker", "email" : "", "dob" : "1990-06-28" } ------------------------------------------------------------- HTTP/1.1 422 Unprocessable Entity Cache-Control: no-cache, private Content-Type: application/json Date: Fri, 20 Sep 2024 16:44:20 GMT Host: 127.0.0.1:8000 X-Powered-By: PHP/8.2.23 X-Robots-Tag: noindex Transfer-Encoding: chunked [ { "path": "email", "error": "Email cannot be empty" } ]
Permintaan imej di atas telah dijana menggunakan fail http.
Mencipta penyelesai tersuai anda
Mari bayangkan kita mempunyai beberapa laluan yang menerima parameter rentetan pertanyaan ke dalam tatasusunan bernama "f". Sesuatu seperti ini:
/my-get-route?f[from]=2024-08-20 16:24:08&f[to]=&f[age]=14
Kami boleh mencipta penyelesai tersuai untuk menyemak tatasusunan itu dalam permintaan dan kemudian mengesahkan data. Jom kodkan.
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\MapQueryString; use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent; use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Validator\Exception\ValidationFailedException; use Symfony\Component\Validator\Validator\ValidatorInterface; class CustomQsValueResolver implements ValueResolverInterface, EventSubscriberInterface { public function __construct( private readonly ValidatorInterface $validator, private readonly SerializerInterface $serializer ){} public static function getSubscribedEvents(): array { return [ KernelEvents::CONTROLLER_ARGUMENTS => 'onKernelControllerArguments', ]; } public function resolve(Request $request, ArgumentMetadata $argument): iterable { $attribute = $argument->getAttributesOfType(MapQueryString::class, ArgumentMetadata::IS_INSTANCEOF)[0] ?? null; if (!$attribute) { return []; } if ($argument->isVariadic()) { throw new \LogicException(sprintf('Mapping variadic argument "$%s" is not supported.', $argument->getName())); } $attribute->metadata = $argument; return [$attribute]; } public function onKernelControllerArguments(ControllerArgumentsEvent $event): void { $arguments = $event->getArguments(); $request = $event->getRequest(); foreach ($arguments as $i => $argument) { if($argument instanceof MapQueryString ) { $qs = $request->get('f', []); if(count($qs) > 0) { $object = $this->serializer->denormalize($qs, $argument->metadata->getType()); $violations = $this->validator->validate($object); if($violations->count() > 0) { $validationFailedException = new ValidationFailedException(null, $violations); throw new UnprocessableEntityHttpException('Unale to process received data', $validationFailedException); } $arguments[$i] = $object; } } } $event->setArguments($arguments); } }
The CustomQsValueResolver implements the ValueResolverInterface and the EventSubscriberInterface, allowing it to resolve arguments for controller actions and listen to specific events in the Symfony event system. In this case, the resolver listens to the Kernel CONTROLLER_ARGUMENTS event.
Let's analyze it step by step:
The constructor
The constructor takes two dependencies: The Validator service for validating objects and a the Serializer service for denormalizing data into objects.
The getSubscribedEvents method
The getSubscribedEvents method returns an array mapping the KernelEvents::CONTROLLER_ARGUMENTS symfony event to the onKernelControllerArguments method. This means that when the CONTROLLER_ARGUMENTS event is triggered (always a controller is reached), the onKernelControllerArguments method will be called.
The resolve method
The resolve method is responsible for resolving the value of an argument based on the request and its metadata.
- It checks if the argument has the MapQueryString attribute. If not, it returns an empty array.
- If the argument is variadic, that is, it can accept a variable number of arguments, it throws a LogicException, indicating that mapping variadic arguments is not supported.
- If the attribute is found, it sets the metadata property of the attribute and returns it as a php iterable.
The onKernelControllerArguments method
The onKernelControllerArguments method is called when the CONTROLLER_ARGUMENTS event is triggered.
- It retrieves the current arguments and the request from the event.
- It iterates over the arguments, checking for arguments flagged as MapQueryString
- If found, it retrieves the query string parameters holded by the "f" array using $request->get('f', []).
- If there are parameters, it denormalizes them into an object of the type specified in the argument's metadata (The Dto class).
- It then validates the object using the validator. If there are validation violations, it throws an UnprocessableEntityHttpException which wraps a ValidationFailedException with the validation errors.
- If validation passes, it replaces the original argument with the newly created object.
Using the resolver in the controller
To instruct the MapQueryString attribute to use our recently created resolver instead of the default one, we must specify it with the attribute resolver value. Let's see how to do it:
#[Route('/my-get-route', name: 'my_route_name', methods: ['GET'])] public function myAction(#[MapQueryString(resolver: CustomQsValueResolver::class)] QueryInputDTO $queryInputDto) { // your code }
Conclusion
In this article, we have analized how symfony makes our lives easier by making common application tasks very simple, such as receiving and validating data from an API. To do that, it offers us the MapQueryString and MapRequestPayload attributes. In addition, it also offers us the possibility of creating our custom mapping resolvers for cases that require specific needs.
If you like my content and enjoy reading it and you are interested in learning more about PHP, you can read my ebook about how to create an operation-oriented API using PHP and the Symfony Framework. You can find it here: Building an Operation-Oriented Api using PHP and the Symfony Framework: A step-by-step guide
Atas ialah kandungan terperinci Cara mudah untuk mengesahkan DTO menggunakan atribut Symfony. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Apa yang masih popular adalah kemudahan penggunaan, fleksibiliti dan ekosistem yang kuat. 1) Kemudahan penggunaan dan sintaks mudah menjadikannya pilihan pertama untuk pemula. 2) Bersepadu dengan pembangunan web, interaksi yang sangat baik dengan permintaan HTTP dan pangkalan data. 3) Ekosistem yang besar menyediakan banyak alat dan perpustakaan. 4) Komuniti aktif dan Sumber Sumber Terbuka menyesuaikan mereka dengan keperluan baru dan trend teknologi.

PHP dan Python adalah kedua-dua bahasa pengaturcaraan peringkat tinggi yang digunakan secara meluas dalam pembangunan web, pemprosesan data dan tugas automasi. 1.Php sering digunakan untuk membina laman web dinamik dan sistem pengurusan kandungan, sementara Python sering digunakan untuk membina kerangka web dan sains data. 2.Php Menggunakan Echo ke Kandungan Output, Python Menggunakan Cetakan. 3. Kedua-dua sokongan pengaturcaraan berorientasikan objek, tetapi sintaks dan kata kunci adalah berbeza. 4. PHP menyokong penukaran jenis lemah, manakala Python lebih ketat. 5. Pengoptimuman Prestasi PHP termasuk menggunakan OPCACHE dan pengaturcaraan asynchronous, manakala Python menggunakan pengaturcaraan CProfile dan tak segerak.

PHP terutamanya pengaturcaraan prosedur, tetapi juga menyokong pengaturcaraan berorientasikan objek (OOP); Python menyokong pelbagai paradigma, termasuk pengaturcaraan OOP, fungsional dan prosedur. PHP sesuai untuk pembangunan web, dan Python sesuai untuk pelbagai aplikasi seperti analisis data dan pembelajaran mesin.

PHP berasal pada tahun 1994 dan dibangunkan oleh Rasmuslerdorf. Ia pada asalnya digunakan untuk mengesan pelawat laman web dan secara beransur-ansur berkembang menjadi bahasa skrip sisi pelayan dan digunakan secara meluas dalam pembangunan web. Python telah dibangunkan oleh Guidovan Rossum pada akhir 1980 -an dan pertama kali dikeluarkan pada tahun 1991. Ia menekankan kebolehbacaan dan kesederhanaan kod, dan sesuai untuk pengkomputeran saintifik, analisis data dan bidang lain.

PHP sesuai untuk pembangunan web dan prototaip pesat, dan Python sesuai untuk sains data dan pembelajaran mesin. 1.Php digunakan untuk pembangunan web dinamik, dengan sintaks mudah dan sesuai untuk pembangunan pesat. 2. Python mempunyai sintaks ringkas, sesuai untuk pelbagai bidang, dan mempunyai ekosistem perpustakaan yang kuat.

PHP tetap penting dalam proses pemodenan kerana ia menyokong sejumlah besar laman web dan aplikasi dan menyesuaikan diri dengan keperluan pembangunan melalui rangka kerja. 1.Php7 meningkatkan prestasi dan memperkenalkan ciri -ciri baru. 2. Rangka kerja moden seperti Laravel, Symfony dan CodeIgniter memudahkan pembangunan dan meningkatkan kualiti kod. 3. Pengoptimuman prestasi dan amalan terbaik terus meningkatkan kecekapan aplikasi.

Phphassignificantelympactedwebdevelopmentandextendsbeyondit.1) itpowersmajorplatformslikeworderpressandexcelsindatabaseIntions.2) php'SadaptabilityAldoStoScaleforlargeapplicationFrameworksLikelara.3)

Jenis PHP meminta untuk meningkatkan kualiti kod dan kebolehbacaan. 1) Petua Jenis Skalar: Oleh kerana Php7.0, jenis data asas dibenarkan untuk ditentukan dalam parameter fungsi, seperti INT, Float, dan lain -lain. 2) Return Type Prompt: Pastikan konsistensi jenis nilai pulangan fungsi. 3) Jenis Kesatuan Prompt: Oleh kerana Php8.0, pelbagai jenis dibenarkan untuk ditentukan dalam parameter fungsi atau nilai pulangan. 4) Prompt jenis yang boleh dibatalkan: membolehkan untuk memasukkan nilai null dan mengendalikan fungsi yang boleh mengembalikan nilai null.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

mPDF
mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

EditPlus versi Cina retak
Saiz kecil, penyerlahan sintaks, tidak menyokong fungsi gesaan kod

Dreamweaver CS6
Alat pembangunan web visual