Исключить свойства null в JMS Serializer
Мой использованный 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
}
]
Ответы
Ответ 1
Вы можете настроить JMS Serializer для пропуска следующих свойств null
:
$serializer = JMS\SerializerBuilder::create();
$serializedString = $serializer->serialize(
$data,
'xml',
JMS\SerializationContext::create()->setSerializeNull(true)
);
Взято из этот вопрос.
UPDATE:
К сожалению, если вы не хотите пустые свойства при десериализации, нет другого пути, кроме как удалить их самостоятельно.
Однако я не уверен, что ваш вариант использования для фактического желания удалить эти свойства, но не похоже, что класс Hotel
содержит много логики. В этом случае мне интересно, должен ли результат быть классом вообще?
Я думаю, что было бы более естественно иметь данные, представленные как ассоциативный массив, а не объект. Конечно, JMS Serializer не может десериализовать ваши данные в массиве, поэтому вам понадобится объект передачи данных.
Достаточно, чтобы вы добавили методы dumpArray
и loadArray
в существующий класс Hotel
. Они будут использоваться для преобразования данных в ваш желаемый результат и наоборот. Существует ваш DTO.
/**
* Sets the object 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
}
Я считаю, что это самый чистый подход, и он может отражать то, что вы пытаетесь сделать больше.
Надеюсь, это поможет.