您必须始终使用字符串值将数据提交到ChoiceType。
考虑以下ChoiceType配置:
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
$builder->add('some_choice', ChoiceType::class, array(
'choices' => array(
'Choose 1' => 1,
'Choose A' => 'A',
'Choose True' => true,
),
));
默认情况下,您可能希望选择数组中的每个键都用作标签,并且每个选择值都将转换为字符串并用作 html 值:
<option value="1">Choose 1</option>
<option value="A">Choose A</option>
<option value="1">Choose True</option>
上面这个例子是错误的。
如您所见,将true 转换为字符串会得到"1",并且它已用于整数1 选择。
所有选择值必须始终是唯一的,因此默认情况下,ChoiceType 使用数字增量:
<option value="0">Choose 1</option>
<option value="1">Choose A</option>
<option value="2">Choose True</option>
相同的情况发生在选择阵列中的某些型号选择值不是标量时(例如,array,@ 987654331,null ...)。
那么提交的数据应该是"0"、"1"或者"2"。每个都将通过ChoiceType 映射到相应的选择。
要完全控制要用于每个选项的字符串值,您可以使用选项choice_value 作为闭包,它将每个选项作为唯一参数传递,并且必须返回其字符串值。
如果您选择的是对象或数组,您可以将其设置为属性路径:
'choice_value' => 'property'
// will be equivalent to
'choice_value' => function ($choice) {
if (is_array($choice)) {
return $choice['property'];
}
if (is_object($choice)) {
return $choice->getProperty();
// or even $choice->isProperty()
}
throw new UnexpectedTypeException();
}
结论:
默认行为与:
$builder->add('some_choice', ChoiceType::class, array(
'choices' => array(
'Choose 1' => 1,
'Choose A' => 'A',
'Choose True' => true,
),
'choice_value' => function ($choice) {
if (!is_scalar($choice) {
return null;
}
return false === $choice ? '0' : (string) $choice;
},
));
如果返回null 或两个相同的值,则将使用递增的整数。
您始终必须提交字符串选择值才能将其映射回ChoiceType。
任何未知值或“额外”值都会导致您的错误。
见official doc