paysera/lib-normalization

库,用于将PHP对象与JSON结构进行规范化与反规范化

1.3.0 2023-05-09 12:58 UTC

This package is auto-updated.

Last update: 2024-09-09 16:06:59 UTC


README

Latest Version on Packagist Software License Build Status Coverage Status Quality Score Total Downloads

此库允许您在不将业务实体(纯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