創建專注的領域應用程式。 Symfony 方法(管理驗證錯誤)
介紹
在上一篇文章中,我們分析了 symfony 序列化器和驗證器元件如何充當基礎設施服務,為我們提供幫助我們在應用程式中執行常見任務的工具。我們也了解了為什麼 UserInputDTO 類別是屬於我們網域的元素,因為它包含業務規則以及如何建立應用程式層服務來執行提取和驗證資料流。
在第二部分中,我們將了解如何管理驗證錯誤,並且正如我們在第一部分中所做的那樣,我們將識別哪些部分屬於該網域。
驗證錯誤
依照使用驗證約束建立的規則驗證 UserInputDTO 後,Symfony 驗證器元件將傳回驗證錯誤。
public function processData(string $content, string $dtoClass): object { $requestData = json_decode($content, true); $userInputDTO = $serializer->denormalize($requestData, UserInputDTO::class); $errors = $validator->validate($userInputDTO); if(count($errors) > 0) { throw new ValidationFailedException($errors); } return $userInputDTO }
如您在上面的程式碼中所看到的,如果驗證方法發現錯誤,則會拋出 ValidationException 類型的例外。從這裡開始,我們必須決定如何向使用者顯示錯誤(網域/業務規則)以及我們將依賴哪些工具以便錯誤正確地到達使用者(基礎設施和應用程式)。
集中捕獲驗證錯誤
我們必須考慮的第一件事是,我們希望在驗證錯誤發生時捕獲它們。為了實現這一目標,我們將依賴基礎設施層。
Symfony 核心附帶了一組內建核心事件來監聽特殊事件。其中一個事件是內核異常事件,當拋出異常時會觸發該事件。讓我們用它來捕獲 ValidationException 錯誤。
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 ValidationFailedException){ // Business rules to build the errors } } }
正如我們在上面的程式碼中所看到的,KernelSubscriber 不斷監聽KernelException 事件,並且僅當捕獲的異常是 ValidationFailedException 類。
從這裡開始,我們必須定義當
onException 方法偵測到這是一個驗證錯誤時將執行的邏輯。
由於我們負責決定如何建置錯誤(我們定義這些業務規則),因此執行邏輯的服務將屬於我們的網域。讓我們來編碼吧
class ValidationErrorsBuilder { public function buildErrors(ValidationFailedException $exception): array { $errors = []; foreach ($exception->getViolations() as $violation) { $errors[$violation->getPropertyPath()] = $violation->getMessage(); } return $errors; } }
ValidationErrorsBuilder 程式碼非常簡單:它循環違規錯誤並建立一個關聯數組,其中鍵是產生錯誤的屬性,值是錯誤訊息。
使用 ValidationErrorsBuilder
現在是時候使用我們的 ValidationErrorsBuilder 網域服務了。我們在 KernelSubscriber onException 方法上使用它。
public function processData(string $content, string $dtoClass): object { $requestData = json_decode($content, true); $userInputDTO = $serializer->denormalize($requestData, UserInputDTO::class); $errors = $validator->validate($userInputDTO); if(count($errors) > 0) { throw new ValidationFailedException($errors); } return $userInputDTO }
如您所見,在知道異常是 ValidationFailedException 後,我們使用網域服務來取得驗證錯誤陣列。
現在,讓我們來看看下面的程式碼:
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 ValidationFailedException){ // Business rules to build the errors } } }
我們新增了新行,在其中設定 Symfony JsonResponse 將錯誤陣列儲存為新回應,並指定傳回的 HTTP 程式碼將是 400 Bad Request。
我們依賴 Symfony Response HTTP_BAD_REQUEST 常數來指定回應 HTTP 程式碼。由於我們在以網域為中心的環境中工作,因此我們可以建立自訂網域類別(例如php 枚舉),但是,由於我們只需要處理標準HTTP 程式碼並且沒有特定的自訂需求,因此我們可以使用Symfony HTTP 程式碼雖然這讓我們更依賴這個框架。
那麼應用層呢?
到目前為止我們還沒有討論應用層。我們在文章一開始就說過,Symfony 框架附帶了一個有用的內建事件,例如我們使用的事件:核心異常事件。此外,symfony框架也為我們提供了EventSubscriberInterface,透過它我們可以建立自訂事件訂閱者並監聽我們需要的事件。
從這些資訊中,我們可以得出結論,symfony 為我們提供了內核異常事件和 EventSubscriberInterface 但我們必須使用該介面來建立訂閱者,指定我們要監聽哪些事件。讓我們繼續:
- 事件訂閱者指定我們監聽內核異常事件。
- 事件訂閱者檢查異常是否為 ValidationFailedException. 的實例
- 事件訂閱者使用網域服務來建立錯誤陣列。
- 事件訂閱者建立包含錯誤的 JsonResponse 並將其設定為最終回應。
這聽起來很熟悉嗎?是的,事件訂閱者負責在拋出異常後管理驗證錯誤的編排和協調,因此我們可以說事件訂閱者將充當應用程式服務。
如果我們想更進一步,我們可以建立一個應用程式層服務並在訂閱者中使用它。
class ValidationErrorsBuilder { public function buildErrors(ValidationFailedException $exception): array { $errors = []; foreach ($exception->getViolations() as $violation) { $errors[$violation->getPropertyPath()] = $violation->getMessage(); } return $errors; } }
public function onException(ExceptionEvent $event): void { $exception = $event->getThrowable(); if($exception instanceof ValidationFailedException){ $errors = $this->validationErrorsBuilder->buildErrors($exception); } }
現在,ValidationErrorsProcessor 將充當協調驗證錯誤回應管理並使用 ValidationErrorsBuilder 網域服務的應用程式服務。
結論
在本系列的第二篇文章中,我們已經確定了驗證錯誤管理過程的哪些元件屬於該網域、我們使用了基礎設施的哪些元素以及核心訂閱者如何充當應用程式服務。
下一篇我們將實體持久化到資料庫中,並分析如何分離將DTO轉換為可持久化實體的邏輯。
以上是創建專注的領域應用程式。 Symfony 方法(管理驗證錯誤)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

PHP在現代化進程中仍然重要,因為它支持大量網站和應用,並通過框架適應開發需求。 1.PHP7提升了性能並引入了新功能。 2.現代框架如Laravel、Symfony和CodeIgniter簡化開發,提高代碼質量。 3.性能優化和最佳實踐進一步提升應用效率。

PHP的核心優勢包括易於學習、強大的web開發支持、豐富的庫和框架、高性能和可擴展性、跨平台兼容性以及成本效益高。 1)易於學習和使用,適合初學者;2)與web服務器集成好,支持多種數據庫;3)擁有如Laravel等強大框架;4)通過優化可實現高性能;5)支持多種操作系統;6)開源,降低開發成本。

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip
