【问题标题】:Exclude null properties in JMS Serializer在 JMS 序列化程序中排除空属性
【发布时间】:2016-07-25 14:08:50
【问题描述】:

我使用的 XML API 可以选择仅检索部分响应。 如果使用此功能,这将导致生成的对象具有大量 NULL 属性。 有没有办法真正跳过NULL 属性?我尝试使用

实施排除策略
shouldSkipProperty(PropertyMetadata $property, Context $context)`

但我意识到没有办法访问当前的属性值。

一个例子是下面的类

class Hotel {
    /**
     * @Type("string")
     */
    public $id;

    /**
     * @Type("integer")
     */
    public $bookable;

    /**
     * @Type("string")
     */
    public $name;

    /**
     * @Type("integer")
     */
    public $type;

    /**
     * @Type("double")
     */
    public $stars;

    /**
     * @Type("MssPhp\Schema\Response\Address")
     */
    public $address;

    /**
     * @Type("integer")
     */
    public $themes;

    /**
     * @Type("integer")
     */
    public $features;

    /**
     * @Type("MssPhp\Schema\Response\Location")
     */
    public $location;

    /**
     * @Type("MssPhp\Schema\Response\Pos")
     */
    public $pos;

    /**
     * @Type("integer")
     */
    public $price_engine;

    /**
     * @Type("string")
     */
    public $language;

    /**
     * @Type("integer")
     */
    public $price_from;
}

在这个特定的 api 调用中反序列化具有大量 null 属性的以下对象。

"hotel": [
    {
        "id": "11230",
        "bookable": 1,
        "name": "Hotel Test",
        "type": 1,
        "stars": 3,
        "address": null,
        "themes": null,
        "features": null,
        "location": null,
        "pos": null,
        "price_engine": 0,
        "language": "de",
        "price_from": 56
    }
]

但我希望它是

"hotel": [
    {
        "id": "11230",
        "bookable": 1,
        "name": "Hotel Test",
        "type": 1,
        "stars": 3,
        "price_engine": 0,
        "language": "de",
        "price_from": 56
    }
]

【问题讨论】:

    标签: php null jms xml-deserialization serialization


    【解决方案1】:

    您可以配置 JMS 序列化程序以跳过 null 属性,如下所示:

    $serializer = JMS\SerializerBuilder::create();              
    $serializedString = $serializer->serialize(
        $data,
        'xml',
        JMS\SerializationContext::create()->setSerializeNull(true)
    );
    

    取自this issue

    更新:

    不幸的是,如果您在反序列化时不想要空属性,那么除了自己删除它们之外别无他法。

    但是,我不确定您实际想要删除这些属性的用例是什么,但它看起来不像 Hotel 类包含太多逻辑。在这种情况下,我想知道结果是否应该是一个类?

    我认为将数据表示为关联数组而不是对象会更自然。当然,JMS Serializer 无法将您的数据反序列化为数组,因此您需要一个数据传输对象。

    dumpArrayloadArray 方法添加到现有的Hotel 类就足够了。这些将用于将数据转换为您想要的结果,反之亦然。有你的 DTO。

    /**
     * Sets the object's properties based on the passed array
     */
    public function loadArray(array $data)
    {
    }
    
    /**
     * Returns an associative array based on the objects properties
     */
    public function dumpArray()
    {
        // filter out the properties that are empty here
    }
    

    我相信这是最干净的方法,它可能反映了您正在尝试做的更多事情。

    我希望这会有所帮助。

    【讨论】:

    • 我实际上已经尝试过了,但它似乎只适用于序列化,不适用于反序列化。
    • 反序列化时如何跳过空属性?如果数据不存在,它将为空。
    • 听起来确实合理。所以我唯一的选择是在获得反序列化对象后递归过滤所有空属性?
    • 我不确定您过滤掉空属性是什么意思。您能否发布一个简单的示例,说明您拥有什么以及您想要完成什么?
    • 我更新了我的答案。如果您觉得它有帮助或者我遗漏了什么,请告诉我。
    猜你喜欢
    • 2015-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    • 1970-01-01
    相关资源
    最近更新 更多