【问题标题】:Serializing nested object private fields序列化嵌套对象私有字段
【发布时间】:2018-02-02 15:47:14
【问题描述】:

我有一个 聚合根 - 产品 - 它的字段很少,其中一些是对象,例如价格。看起来是这样的(当然是简化了):

Product
{
    private $price;

    public function __construct(Price $price)
    {
       $this->price = $price;
    }
}


Price
{

    private $currency;
    private $amount;

    public function __construct($currency, $amount)
    {
       $this->currency = $currency;
       $this->amount= $amount;
    }
}

此聚合根不包含“getPrice”方法,在域中不需要。

问题: 我需要序列化这个聚合,但我希望它采用这种格式:

产品.json

{    
    "priceCurrency": "GBP",
    "priceAmount": 100 
}

我一直在尝试使用 JMSSerializer,但无法从配置中真正得到它。例如,这不起作用

Product.yml

Namespace\Product:
   virtual_properties:
     getAmount:
         exp: object.price.amount
         serialized_name: priceAmount
         type: integer
     getCurrency:
         exp: object.price.currency
         serialized_name: priceCurrency
         type: string

我知道这是因为 Symfony 表达式语言正在使用“exp”部分,并且据我所知,它不支持以任何其他方式从私有字段获取值,然后通过他们的方法。我也知道 JMSSerializer 本身支持这一点。我不必有字段“getPrice”来序列化“价格”字段。

问题:有什么方法可以通过配置实现我想要的,还是我必须在 post_serialize 事件上编写监听器?

【问题讨论】:

  • 您为什么要使用虚拟属性而不只是在属性本身上设置serialized_name
  • 嗯?这对我有什么帮助? serialized_name 只是序列化字段的名称,我无法获取值,而不是设置名称。
  • 也许我误解了问题所在...我认为 JMS 只是使用反射来获取私有字段值。这就是你遇到的问题吗?还是您试图从关联对象中获取特定值的事实?

标签: php symfony serialization jmsserializerbundle


【解决方案1】:

使用这样的东西:

<?php

class Property
{
    protected $reflection;
    protected $obj;

    public function __construct($obj)
    {
        $this->obj = $obj;
        $this->reflection = new ReflectionObject($obj);
    }

    public function set($name, $value)
    {
        $this->getProperty($name)->setValue($this->obj, $value);
    }

    public function get($name)
    {
        return $this->getProperty($name)->getValue($this->obj);
    }

    protected function getProperty($name)
    {
        $property = $this->reflection->getProperty($name);
        $property->setAccessible(true);
        return $property;
    }
}

// example
class Foo
{
    protected $bar = 123;

    public function getBar()
    {
        return $this->bar;
    }
}

$foo = new Foo();
echo 'original: '.$foo->getBar().PHP_EOL;

$prop = new Property($foo);
echo 'reflection - before changes: '.$prop->get('bar').PHP_EOL;

$prop->set('bar', 'abc');

echo 'after changes: '.$foo->getBar().PHP_EOL;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多