#php #symfony #deserialization
#php #symfony #десериализация
Вопрос:
Я новичок в сериализации объектов, и мне трудно понять, как / где я могу вставить сопоставление между полями объекта и заголовками CSV.
В настоящее время я создаю форму загрузки CSV и пытаюсь использовать CSVEncoder для десериализации строк CSV в массив объектов.
Теперь это работает, когда заголовки идеальны, но я надеялся добавить какое-то сопоставление заголовков в CSVEncoder, чтобы сопоставить заголовки с полями.
Пример
class Person
{
public $name;
public $age;
public $email;
}
Заголовки CSV, подобные приведенным ниже, будут идеально отображать строки
'name,age,email'
но я хотел бы добавить какое-то сопоставление, чтобы позволить подобным заголовкам также сопоставляться с соответствующим полем
'full name,aged,email address'
Ссылки:
https://symfony.com/doc/current/components/serializer.html
Возможно, мои навыки поиска в Google невелики, потому что я думал, что это будет обычным явлением при попытке десериализации CSV.
У меня есть несериализованная версия, которая считывает файл и преобразует строки в объекты, но это очень медленно, и я хотел бы улучшить этот код (и свои навыки), делая все «правильно».
В этой другой версии я читаю строку заголовка, сравниваю ее с ассоциативным массивом, который отображает правильный заголовок и массив приемлемых псевдонимов, а затем переписываю заголовки с их правильными заголовками.
Я мог бы сделать это снова перед передачей файла в CSVEncoder, но мне интересно, есть ли лучший, менее уродливый способ сделать это.
Приветствия
Ответ №1:
Вы должны использовать NameConverter, проверьте это https://symfony.com/doc/current/components/serializer.html#converting-property-names-when-serializing-and-deserializing
Итак, ваш конвертер имен может выглядеть следующим образом:
use SymfonyComponentSerializerNameConverterNameConverterInterface;
class MappingNameConverter implements NameConverterInterface {
public function __construct(array $mapping) {
$this->mapping = $mapping;
}
public function denormalize($propertyName)
{
return $this->mapping[$propertyName];
}
}
и вы должны использовать это так:
use SymfonyComponentSerializerEncoderCsvEncoder;
use SymfonyComponentSerializerNormalizerObjectNormalizer;
use SymfonyComponentSerializerSerializer;
$mapping = ['full name' => 'name', 'aged' => 'age', ...];
$nameConverter = new MappingNameConverter($mapping);
$normalizer = new ObjectNormalizer(null, $nameConverter);
$serializer = new Serializer([$normalizer], [new CsvEncoder()]);
Я не тестировал код, но что-то подобное должно сработать 🙂
Комментарии:
1. Спасибо! Я прочитал это, но я совершенно неправильно понял это. Я думал, что это просто добавление ‘org_’ к значениям, а не к ключам.
2. Просто несколько строк кода, объясняющих концепцию. Молодец, Винсент. Спасибо! Я не знаю, почему документы Symfony иногда такие криптические.