Компонент 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: