Как добавить сопоставления псевдонимов полей для десериализации

#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 иногда такие криптические.