Я запускаю 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)
попробуйте добавить 'empty_value' => null
Вы должны использовать 'расширенный' => ложный и 'множественный' => истинный.
@MatthewUsurp Я добавил трассировку стека в свою первую тему.
@gogaz Если я добавлю его, я получу новую ошибку: параметр "empty_value" не существует
Вы проводили какое-либо исследование? Ваш вопрос очень похож на этот stackoverflow.com/questions/17314996/…
@JasminMistry: он генерирует НЕСКОЛЬКО <select>, и я стараюсь иметь УНИКАЛЬНЫЙ <select>






для решения вашей проблемы вам нужен преобразователь данных, потому что поле ролей на самом деле является массивом:
добавьте преобразователь данных в свой класс 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, я предлагаю вам взглянуть на ответ отвечать, который является вашей проблемой.
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];
}
));
}
Есть ли дополнительная информация в трассировке стека?