上下文
通过使用JMS串行化库,我需要序列化/取消序列化内部由php支持枚举表示的数据。
有什么问题吗?
我通过使用SubscribingHandlerInterface接口找到了一个解决方案,但是我想简化这个过程,方法是删除(如果可能的话)一个样板类,这个类必须为每个新枚举创建。
实际工作代码,需简化
<?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序列化/反序列化。
发布于 2022-11-09 20:44:54
这是很麻烦的,但这至少适用于反序列化作为对象属性的后台枚举。
public function deserializeEnum(
JsonDeserializationVisitor $visitor,
$value,
array $type,
Context $context
) {
$targetProperty = new ReflectionProperty(
$visitor->getCurrentObject()::class,
$context->getCurrentPath()[
array_key_last($context->getCurrentPath())
]
);
$targetPropertyType = $targetProperty->getType()->getName();
$targetPropertyNullable = $targetProperty->getType()->allowsNull();
if ($value === null && $targetPropertyNullable) {
return null;
}
return $targetPropertyType::from($value);
}https://stackoverflow.com/questions/73115015
复制相似问题