| Вопрос | А
| ---------------- | -----
| Сообщение об ошибке? | нет
| Запрос функции? | да
| Отчет о перерыве в БК? | нет
| RFC? | нет
| Версия Symfony | 3.3.0
Было бы очень полезно, если бы существовал способ рекурсивной десериализации объектов.
Учитывая такой объект:
class User
{
/**
* Set Name.
*
* <strong i="15">@param</strong> Name $name
*/
public function setName(Name $name) : self
{
$this->name = $name;
return $this;
}
}
Сериализатор выдает Symfony\Component\Serializer\Exception\UnexpectedValueException
с сообщением «Ожидаемый аргумент типа ‘Имя’, ‘массив’ указан», потому что он передает массив в setName()
, а не выполняет денормилизацию на Name
класс, а затем передать результат в setName()
.Я мог бы, конечно, разрешить этому методу принимать имя и массив, но тогда он пропустит:
1) Заполнение существующего объекта имени
2) Любые группы, которые могут быть использованы для доступа.
Поскольку у метода уже есть подсказка типа единственного, что он примет (класс), я думаю, имеет смысл, если в сеттере встречается подсказка нескалярного типа, он должен:
1) Запустите денормализатор с классом подсказки типа в качестве типа.
2) Передать те же группы от родителя к ребенку
3) Попытка получить значение свойства, если значение возвращается, оно должно использовать это значение в object_to_populate
(при условии, что object_to_populate
было установлено для родителя)
Ну, это было не сразу очевидно, но я нашел это:
https://github.com/symfony/symfony/blob/3.2/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml#L25
что привело меня к установке компонента ProperyInfo и включению его в моем config.yml
:
framework:
property_info:
enabled: true
Это _в основном_ решает мои проблемы. Он поддерживает рекурсию и группы, однако не поддерживает object_to_populate
. Я собираюсь изменить этот вопрос, чтобы он касался этого, а не самой рекурсии, которую Symfony явно поддерживает (хотя и плохо документирован).
В документации отсутствует информация о том, как вам нужно активировать PropertyInfo, чтобы десериализовать встроенный объект, я уже писал об этом: https://github.com/symfony/symfony-docs/issues/7387
Что касается третьей проблемы (теперь только проблемы), object_to_populate используется для обновления/использования уже существующего объекта вместо создания нового. Вы говорите, что если родитель использует эту опцию, встроенные объекты также должны ее использовать. Я вижу необходимость использовать существующий объект в качестве значения свойства, но:
Комментарий @davidbarratt помог мне понять, что мне нужно установить PropertyInfoComponent
и добавить конфигурацию framework.property_info.enabled
, чтобы сериализатор мог десериализовать объекты со свойствами \DateTime
. Это не обязательно для сериализации, и я не смог найти ничего в документе, где это упоминается.
Без этого сериализация объекта со свойством \DateTime
работает, но его десериализация сразу после этого терпит неудачу. Это (сериализация _и десериализация_ объектов со свойствами \DateTime
) кажется вероятным сценарием, поэтому я бы предложил упомянуть об этом в документации, чтобы избавить других разработчиков от разочарования и лихорадочного гугления.
Самый полезный комментарий
Ну, это было не сразу очевидно, но я нашел это:
https://github.com/symfony/symfony/blob/3.2/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml#L25
что привело меня к установке компонента ProperyInfo и включению его в моем
config.yml
:Это _в основном_ решает мои проблемы. Он поддерживает рекурсию и группы, однако не поддерживает
object_to_populate
. Я собираюсь изменить этот вопрос, чтобы он касался этого, а не самой рекурсии, которую Symfony явно поддерживает (хотя и плохо документирован).