【问题标题】:JMS Serializer: Dynamically change the name of a virtual property at run timeJMS Serializer:在运行时动态更改虚拟属性的名称
【发布时间】:2014-10-13 08:09:07
【问题描述】:

我使用 JMS Serializer Bundle 和 Symfony2。我正在使用虚拟属性。目前,我使用 SerializedName 注释设置属性的名称。

 /**
 * @JMS\VirtualProperty()
 * @JMS\SerializedName("SOME_NAME")
 */
public function getSomething()
{
    return $this->something
}

是否可以在函数内部动态设置序列化名称?或者是否可以使用 Post/Pre 序列化事件动态影响名称?

谢谢!

【问题讨论】:

  • 你为什么需要那个?
  • 我有一个实体层,它由学说对象和一个 API 层组成。每个 API 对象都有一个属性“实体”,其中包含一个相应的实体。它具有 VirtualProperties,它们是实体的一种访问器。在 VirtualProperties 内部,我可以控制来自实体层的信息如何显示给用户。例如。多对多关系的实体具有属性“源”和“目标” - 当我访问此实体时,只有源或目标是相关的,但我在运行时决定这一点,我想用相关属性将其交给外部名字。
  • 您找到解决方案了吗?我自己就是这样的。

标签: symfony jmsserializerbundle jms-serializer


【解决方案1】:

我认为您不能直接执行此操作,但您可以通过拥有多个虚拟属性来完成类似的操作,每个虚拟属性对应一个可能的名称。如果名称与特定实体无关,则让方法返回 null,并在 JMS 配置中禁用 null 序列化。

【讨论】:

  • 感谢您的回答,我现在就是这样做的,但这并不是一个很好的解决方案。
【解决方案2】:

在你去序列化对象的那一刻,执行以下操作:

$this->serializer = SerializerBuilder::create()->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy())->build();

$json = $this->serializer->serialize($object, 'json');
dump($json);

【讨论】:

    【解决方案3】:

    实体

    /**
     * @JMS\VirtualProperty("something", exp="context", options={
     *     @JMS\Expose,
     * })
     */
    class SomeEntity
    {
    }
    

    事件监听器

    abstract class AbstractEntitySubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents(): array
        {
            return [
                [
                    'event'    => Events::POST_SERIALIZE,
                    'method'   => 'onPostSerialize',
                    'class'    => static::getClassName(),
                    'format'   => JsonEncoder::FORMAT,
                    'priority' => 0,
                ],
            ];
        }
    
        public function onPostSerialize(ObjectEvent $event): void
        {
            foreach ($this->getMethodNames() as $methodName) {
                $visitor  = $event->getVisitor();
                $metadata = new VirtualPropertyMetadata(static::getClassName(), $methodName);
    
                if ($visitor->hasData($metadata->name)) {
                    $value = $this->{$methodName}($event->getObject());
                    $visitor->visitProperty(
                        new StaticPropertyMetadata(static::getClassName(), $metadata->name, $value),
                        $value
                    );
                }
            }
        }
    
        abstract protected static function getClassName(): string;
    
        abstract protected function getMethodNames(): array;
    }
    

    ...

    class SomeEntitySubscriber extends AbstractEntitySubscriber
    {
        protected static function getClassName(): string
        {
            return SomeEntity::class;
        }
    
        protected function getMethodNames(): array
        {
            return ['getSomething'];
        }
    
        protected function getSomething(SomeEntity $someEntity)
        {
            return 'some text';
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-22
      • 2017-07-28
      • 2013-06-29
      • 1970-01-01
      • 2018-01-10
      • 1970-01-01
      • 2017-10-14
      • 2020-03-16
      相关资源
      最近更新 更多