Компонент Symfony3 Form, пытающийся передать значение null в тип намеченного метода в PHP 7
В моем классе сущности я определил все ожидаемые типы аргументов для сеттеров и возвращаемых типов геттеров.
Позже, когда у меня есть форма, которая использует указанный класс, я получаю сообщение об ошибке, если некоторые из полей в форме пустые, потому что компонент формы пытается передать null в сеттер вместо строки.
Я получаю следующее исключение, когда я отправляю форму:
Ожидаемый аргумент типа "string", "NULL", указанный
500 Внутренняя ошибка сервера - InvalidArgumentException
Исключение выбрано из vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php at line 254
Есть ли способ преобразовать значение "null" в пустую строку, прежде чем передать его объекту, и пусть валидатор спорит об этом?
Ответы
Ответ 1
Здесь я вижу два варианта:
Быстрая и грязная - добавьте аргумент, переданный параметру 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 раньше. Посмотрите, если это поможет увидеть более сложный пример.
Ответ 2
Если свойство Entity не может быть null
(и вы используете PHP 7.1+), то также приложение объявление типа nullable return type звучит скорее как грязное и быстрое обходное решение для поддержания прямой привязки данных между объектами и формами (с использованием компонента формы Symfony).
Лучшим глобальным подходом (на мой взгляд) является развязка привязки данных формы от ваших Сущностей с использованием DTO (Data Transfert Object), который является простым POPO (Plain Old PHP Object), чтобы содержать ваши данные формы.
Использование DTO позволит вам поддерживать строгие типы намеков в ваших сущностях (без потери согласованности данных) и будет отделять привязку данных к формам (но также и проверку данных) от ваших объектов.
DTO допускает повторное использование и имеет много других преимуществ.
Некоторые полезные справки об использовании DTO с Symfony Forms: