Форма Symfony - Выбор типа - Ошибка "Массив в совпадение строк"

Я запускаю Symfony 3.4 с FosUserBundle. Я настроил регистрационную форму, чтобы включить Roles:

<?php

    $form->add('roles', ChoiceType::class, array(
        'choices' => array(
            'user' => 'ROLE_USER',
            'admin' => 'ROLE_ADMIN'
        ),
        'label' => 'Role :',
        'expanded' => true,
        'multiple' => true
    ));

Затем роли теперь можно выбирать в регистрационной форме с помощью 2 новых флажков ... но я бы хотел отобразить его с помощью тега <select>. Когда я устанавливаю для параметра expanded значение false, я получаю выбор, но если я устанавливаю для параметра multiple значение FALSE, я получаю сообщение об ошибке:

Array to string conversion

Есть идеи исправить мою проблему?

Обновлено: ниже приведена трассировка стека:

Symfony\Component\Debug\Exception\ContextErrorException:
Notice: Array to string conversion

  at vendor\symfony\symfony\src\Symfony\Component\Form\ChoiceList\ArrayChoiceList.php:73
  at Symfony\Component\Form\ChoiceList\ArrayChoiceList->Symfony\Component\Form\ChoiceList\{closure}(array('ROLE_USER'))
  at call_user_func(object(Closure), array('ROLE_USER'))
     (vendor\symfony\symfony\src\Symfony\Component\Form\ChoiceList\ArrayChoiceList.php:158)
  at Symfony\Component\Form\ChoiceList\ArrayChoiceList->getValuesForChoices(array(array('ROLE_USER')))
     (vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToValueTransformer.php:32)
  at Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToValueTransformer->transform(array('ROLE_USER'))
     (vendor\symfony\symfony\src\Symfony\Component\Form\Form.php:1104)
  at Symfony\Component\Form\Form->normToView(array('ROLE_USER'))
     (vendor\symfony\symfony\src\Symfony\Component\Form\Form.php:350)
  at Symfony\Component\Form\Form->setData(array('ROLE_USER'))
     (vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper.php:49)
  at Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper->mapDataToForms(object(User), object(RecursiveIteratorIterator))
     (vendor\symfony\symfony\src\Symfony\Component\Form\Form.php:383)
  at Symfony\Component\Form\Form->setData(object(User))
     (vendor\friendsofsymfony\user-bundle\Controller\RegistrationController.php:70)
  at FOS\UserBundle\Controller\RegistrationController->registerAction(object(Request))
  at call_user_func_array(array(object(RegistrationController), 'registerAction'), array(object(Request)))
     (var\cache\dev\classes.php:4659)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (var\cache\dev\classes.php:4614)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php:200)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (web\app_dev.php:29)

Есть ли дополнительная информация в трассировке стека?

Matthew Usurp 08.08.2018 12:36

попробуйте добавить 'empty_value' => null

gogaz 08.08.2018 12:41

Вы должны использовать 'расширенный' => ложный и 'множественный' => истинный.

Jasmin Mistry 08.08.2018 12:53

@MatthewUsurp Я добавил трассировку стека в свою первую тему.

Paolito75 08.08.2018 14:56

@gogaz Если я добавлю его, я получу новую ошибку: параметр "empty_value" не существует

Paolito75 08.08.2018 14:57

Вы проводили какое-либо исследование? Ваш вопрос очень похож на этот stackoverflow.com/questions/17314996/…

Thai Duong Tran 08.08.2018 14:58

@JasminMistry: он генерирует НЕСКОЛЬКО <select>, и я стараюсь иметь УНИКАЛЬНЫЙ <select>

Paolito75 08.08.2018 14:58
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
3
7
3 669
3

Ответы 3

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

добавьте преобразователь данных в свой класс FormType вместе с полем ролей вместо того, чтобы добавлять его в контроллер:

$builder->add('roles', ChoiceType::class, array(
    'choices' => array(
        'user' => 'ROLE_USER',
        'admin' => 'ROLE_ADMIN'
    ),
    'label' => 'Role :'
));

//roles field data transformer
$builder->get('roles')
    ->addModelTransformer(new CallbackTransformer(
        function ($rolesArray) {
             // transform the array to a string
             return count($rolesArray)? $rolesArray[0]: null;
        },
        function ($rolesString) {
             // transform the string back to an array
             return [$rolesString];
        }
));

То, что происходит, нормально: ваши роли свойства - это массив строк. В вашей сущности у вас есть что-то вроде:

/**
 * @var array
 */
private $roles = [];

И логически, когда вы устанавливаете опцию multiple => 'true', форма Symfony будет рассматривать его как массив и преобразовывать каждый элемент вашего массива в строку (которая уже есть).

С другой стороны, если вы поставите multiple => false, массив будет рассматриваться как единственный вариант, а это не так.

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

В вашем случае вы должны поставить несколько => true.

Если вы упорно хотите, чтобы несколько => false, я предлагаю вам взглянуть на ответ отвечать, который является вашей проблемой.

letibelim 08.08.2018 16:27

2020 - Symfony 5.0.8:

в вашем файле FormType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('roles', ChoiceType::class, [
            'required' => true,
            'multiple' => false,
            'expanded' => false,
            'choices'  => [
                'User' => 'ROLE_USER',
                'Admin' => 'ROLE_ADMIN',
            ],
        ]);

    $builder->get('roles')
        ->addModelTransformer(new CallbackTransformer(
            function ($rolesArray) {
                // transform the array to a string
                return count($rolesArray)? $rolesArray[0]: null;
            },
            function ($rolesString) {
                // transform the string back to an array
                return [$rolesString];
            }
        ));
}

Другие вопросы по теме