paysera / lib-normalization
库,用于将PHP对象与JSON结构进行规范化与反规范化
1.3.0
2023-05-09 12:58 UTC
Requires
- php: ^7.0 || ^8.0
- paysera/lib-object-wrapper: ~0.3
Requires (Dev)
- ext-json: *
- mockery/mockery: ^1.2
- phpunit/phpunit: ^6.5 || ^9.0
README
此库允许您在不将业务实体(纯PHP对象)与规范化格式紧密耦合的情况下进行去/规范化。您通常会在将规范化结构转换为JSON之前或之后进行此操作。
如果您打算与Symfony一起使用此库,请使用 lib-normalization-bundle 代替。
为什么?
Symfony组件具有Serializer组件,其中包含规范化器作为其一部分。该组件出于类似原因创建,但采用了不同的方法。
Symfony组件默认公开您的业务实体,但允许复杂的但具有挑战性的配置选项。它还允许编写自定义规范化逻辑,但通常位于您的规范化类(可能是纯PHP对象)中。
Paysera规范化库通过始终编写一些代码来拥抱简单性,从而获得对情况的完全控制 - 规范化逻辑位于相关类中,这些类通常由DIC注册。这允许使用其他服务、从数据库获取数据、在需要时调用远程服务或执行其他任何操作,所有这些都在熟悉的PHP源代码中。您可以轻松重命名任何字段,使用任何自定义命名,为向后兼容性复制一些数据,或者,好吧,只是编写其他代码。对于边缘情况,您无需复杂的配置,因为您对情况有完全的控制。
此库的主要功能
- 通过集成 lib-object-wrapper,在反规范化时支持显式类型安全;
- 可以通过传递的数据猜测规范化类型;
- 可以轻松重用其他去/规范化器,而无需直接依赖;
- 支持不同的规范化组,并提供默认组的回退;
- 支持显式或隐式包含的字段,允许在规范化过程中调整性能。
安装
composer require paysera/lib-normalization
使用
基本用法
为您的业务实体编写去/规范化器
<?php // ... class ContactDetailsNormalizer implements NormalizerInterface, ObjectDenormalizerInterface, TypeAwareInterface { public function getType(): string { return ContactDetails::class; } /** * @param ContactDetails $data * @param NormalizationContext $normalizationContext * * @return array */ public function normalize($data, NormalizationContext $normalizationContext) { return [ 'email' => $data->getEmail(), // will automatically follow-up with normalization by guessed types: 'residence_address' => $data->getResidenceAddress(), 'shipping_addesses' => $data->getShippingAddresses(), ]; } public function denormalize(ObjectWrapper $data, DenormalizationContext $context) { return (new ContactDetails()) ->setEmail($data->getRequiredString('email')) ->setResidenceAddress( $context->denormalize($data->getRequiredObject('residence_address'), Address::class) ) ->setShippingAddresses( $context->denormalizeArray($data->getArrayOfObject('shipping_addesses'), Address::class) ) ; } }
<?php // ... class AddressNormalizer implements NormalizerInterface, ObjectDenormalizerInterface, TypeAwareInterface { private $countryRepository; private $addressBuilder; // ... public function getType(): string { return Address::class; } /** * @param Address $data * @param NormalizationContext $normalizationContext * * @return array */ public function normalize($data, NormalizationContext $normalizationContext) { return [ 'country_code' => $data->getCountry()->getCode(), 'city' => $data->getCity(), 'full_address' => $this->addressBuilder->buildAsText($data->getStreetData()), ]; } public function denormalize(ObjectWrapper $data, DenormalizationContext $context) { $code = $data->getRequiredString('country_code'); $country = $this->countryRepository->findOneByCode($code); if ($country === null) { throw new InvalidDataException(sprintf('Unknown country %s', $code)); } return (new Address()) ->setCountry($country) ->setCity($data->getRequiredString('city')) ->setStreetData( $this->addressBuilder->parseFromText($data->getRequiredString('full_address')) ) ; } }
在提供者中注册所有去/规范化器
<?php $provider = new GroupedNormalizerRegistryProvider(); $provider->addTypeAwareNormalizer(new ContactDetailsNormalizer()); $provider->addTypeAwareNormalizer(new AddressNormalizer(/* ... */));
创建所需的服务
$coreDenormalizer = new CoreDenormalizer($provider); $coreNormalizer = new CoreNormalizer($provider, new TypeGuesser(), new DataFilter());
用于去/规范化
// must be stdClass, not array $data = json_decode('{ "email":"a@example.com", "residence_address":{"country_code":"LT","city":"Vilnius","full_address":"Park street 182b-12"}, "shipping_addresses":[] }'); $contactDetails = $coreDenormalizer->denormalize($data, ContactDetails::class); $normalized = $coreNormalizer->normalize($contactDetails); var_dump($normalized); // object(stdClass)#1 (3) { ...
对于高级用法,请参阅 lib-normalization-bundle 和源代码。
如果您有任何问题,请随时创建问题。
语义版本控制
此库遵循 语义版本控制。
有关API中可以更改的内容和不可以更改的内容的基本信息,请参阅 Symfony BC规则。
运行测试
composer update
composer test
贡献
请随时创建问题和提交拉取请求。
您可以使用以下命令修复任何代码风格问题
composer fix-cs