介绍
在上一篇文章中,我们分析了 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中文网其他相关文章!

TheSecretTokeEpingAphp-PowerEdwebSiterUnningSmoothlyShyunderHeavyLoadInVolvOLVOLVOLDEVERSALKEYSTRATICES:1)emplactopCodeCachingWithOpcachingWithOpCacheToreCescriptexecution Time,2)使用atabasequercachingCachingCachingWithRedataBasEndataBaseLeSendataBaseLoad,3)

你应该关心DependencyInjection(DI),因为它能让你的代码更清晰、更易维护。1)DI通过解耦类,使其更模块化,2)提高了测试的便捷性和代码的灵活性,3)使用DI容器可以管理复杂的依赖关系,但要注意性能影响和循环依赖问题,4)最佳实践是依赖于抽象接口,实现松散耦合。

是的,优化papplicationispossibleandessential.1)empartcachingingcachingusedapcutorediucedsatabaseload.2)优化的atabaseswithexing,高效Quereteries,and ConconnectionPooling.3)EnhanceCodeWithBuilt-unctions,避免使用,避免使用ingglobalalairaiables,并避免使用

theKeyStrategiestosiminificallyBoostphpapplicationPermenCeare:1)useOpCodeCachingLikeLikeLikeLikeLikeCacheToreDuceExecutiontime,2)优化AtabaseInteractionswithPreparedStateTemtStatementStatementSandProperIndexing,3)配置

aphpdepentioncontiveContainerIsatoolThatManagesClassDeptions,增强codemodocultion,可验证性和Maintainability.itactsasaceCentralHubForeatingingIndections,因此reducingTightCightTightCoupOulplingIndeSingantInting。

选择DependencyInjection(DI)用于大型应用,ServiceLocator适合小型项目或原型。1)DI通过构造函数注入依赖,提高代码的测试性和模块化。2)ServiceLocator通过中心注册获取服务,方便但可能导致代码耦合度增加。

phpapplicationscanbeoptimizedForsPeedAndeffificeby:1)启用cacheInphp.ini,2)使用preparedStatatementSwithPdoforDatabasequesies,3)3)替换loopswitharray_filtaray_filteraray_maparray_mapfordataprocrocessing,4)conformentnginxasaseproxy,5)

phpemailvalidation invoLvesthreesteps:1)格式化进行regulareXpressecthemailFormat; 2)dnsvalidationtoshethedomainhasavalidmxrecord; 3)


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

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

Dreamweaver CS6
视觉化网页开发工具

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)