【问题标题】:Automatically implementing JMS serialization for many php backed enums为许多 php 支持的枚举自动实现 JMS 序列化
【发布时间】:2022-11-10 04:44:54
【问题描述】:

语境

通过使用JMS serializer library,我需要序列化/反序列化由 php 支持的枚举内部表示的数据。

有什么问题

我通过使用SubscribingHandlerInterface interface 找到了一个解决方案,但我想通过删除(如果可能)一个必须创建的样板类来简化该过程对于每个新枚举.

实际工作代码,待简化

  • 示例枚举:
<?php

namespace App\Enum;

enum MyEnum: string
{
    case Hello = 'hello';
    case World = 'world';
}
  • 这个抽象类是为了尽量减少最终类的冗余代码(我想“删除”的那些):
<?php

namespace App\Serializer;

use JMS\Serializer\GraphNavigator;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonDeserializationVisitor;
use JMS\Serializer\SerializationContext;
use JMS\Serializer\Visitor\SerializationVisitorInterface;
use LogicException;

abstract class AbstractEnumSerializer implements SubscribingHandlerInterface
{
    public static function getEnumClass(): string
    {
        throw new LogicException("Please implement this");
    }

    public static function getSubscribingMethods(): array
    {
        return [
            [
                'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
                'format' => 'json',
                'type' => static::getEnumClass(),
                'method' => 'deserializeFromJSON',
            ], [
                'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
                'format' => 'json',
                'type' => static::getEnumClass(),
                'method' => 'serializeToJSON',
            ],
        ];
    }

    public function deserializeFromJSON(JsonDeserializationVisitor $visitor, $data, array $type)
    {
        return static::getEnumClass()::tryFrom($data);
    }

    public function serializeToJSON(
        SerializationVisitorInterface $visitor,
        $enum,
        array $type,
        SerializationContext $context
    ): string
    {
        return $enum->value;
    }
}
  • 这是我要“删除”的课程,通过首选某种自动生成/注册:它为上述示例枚举实现(反)序列化,但它是样板代码,需要对于每个新枚举
<?php

namespace App\Serializer;

use App\Enum\MyEnum;

class MyEnumSerializer extends AbstractEnumSerializer
{
    public static function getEnumClass(): string
    {
        return MyEnum::class;
    }
}

问题

让我们假设许多 php 支持的枚举必须被(反)序列化;通过更喜欢某种自动生成/注册,是否可以避免为每个枚举编写 MyEnumSerializer 类?

主要目标是保持简单地添加新的支持枚举,同时为它们自动实现 JMS 序列化/反序列化。

【问题讨论】:

    标签: php enums php-8 jms-serializer


    【解决方案1】:

    这很hacky,但这至少适用于将支持的枚举反序列化为对象属性。

    public function deserializeEnum(JsonDeserializationVisitor $visitor, $value, array $type, Context $context)
    {
        $targetProperty = new ReflectionProperty($visitor->getCurrentObject()::class, $context->getCurrentPath()[0]);
        $targetPropertyType = $targetProperty->getType()->getName();
        $targetPropertyNullable = $targetProperty->getType()->allowsNull();
    
        if ($value === null && $targetPropertyNullable) {
            return null;
        }
    
        return $targetPropertyType::from($value);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-10-25
      • 2021-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      相关资源
      最近更新 更多