Компонент Symfony3 Form, пытающийся передать значение null в тип намеченного метода в PHP 7

В моем классе сущности я определил все ожидаемые типы аргументов для сеттеров и возвращаемых типов геттеров. Позже, когда у меня есть форма, которая использует указанный класс, я получаю сообщение об ошибке, если некоторые из полей в форме пустые, потому что компонент формы пытается передать null в сеттер вместо строки.

При отправке формы я получаю следующее исключение:

Ожидаемый аргумент типа «строка», «NULL»

500 Внутренняя ошибка сервера – InvalidArgumentException

Исключение выбрано из vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php at line 254

Есть ли способ конвертировать значение «null» в пустую строку, прежде чем передать его объекту, и пусть валидатор спорит об этом?

Здесь я вижу два варианта:

Быстрая и грязная – сделайте аргумент, переданный параметру setter дополнительно:

 public function setTitle(String $title = null) { $this->title = $title; return $this; } 

Вероятно, лучше – используйте преобразователь данных в FormType:

Трансформаторы данных позволяют вам изменять данные до их использования.

  $builder // ... ->add('title', 'text') // ... ; $builder->get('title')->addModelTransformer(new CallbackTransformer( function($originalInput){ return $string; }, function($submittedValue){ // When null is cast to a string, it will be empty. return (string) $submittedValue; } )); 

Я написал еще один ответ, прежде чем использовать этот метод для извлечения метода для извлечения объекта Entity. Смотрите, если это поможет увидеть более сложный пример.

Если свойство Entity никогда не может быть null ( и вы используете PHP 7.1+ ), то также применение объявления типа nullable return type похоже на грязное и быстрое обходное решение для поддержания прямой привязки данных между Entities и Forms ( с использованием формы Symfony Компонент ).

Лучший глобальный подход ( на мой взгляд ) состоит в том, чтобы отделить привязку данных формы от ваших Сущностей, используя DTO ( Data Transfert Object ), который является простым POPO ( Plain Old PHP Object ), чтобы содержать ваши данные формы.

Использование DTO позволит вам поддерживать строгие типы намеков в ваших сущностях ( без потери согласованности данных ) и будет отделять привязку данных формы ( но также и проверку данных ) от ваших сущностей.

DTO позволяет повторно использовать и имеет много других преимуществ.

Некоторые полезные ссылки об использовании DTO с Symfony Forms:

  • Избегание сущностей в формах ( Илтар ван дер Берг )
  • Переосмысление формы развития ( Илтар ван дер Берг )
  • Symfony Forms 101 ( автор Бернхард Шуссек, создатель компонента Form )