我在Symfony 3.1.6上运行,而且表单渲染让我感到奇怪。
这是我的表格:
$form = $this->createFormBuilder()
->add('foo', ChoiceType::class, [
'choices' => [
'00 h 30' => 0.5,
'01 h 00' => 1.0,
],
])
->add('bar', ChoiceType::class, [
'choices' => [
'00 h 30' => 0.5,
'01 h 00' => 1.0,
'01 h 30' => 1.5,
],
])
->add('baz', ChoiceType::class, [
'choices' => [
'00 h 30' => 0.5,
'01 h 00' => 1.0,
'02 h 00' => 2.0,
],
])
->getForm();
基本渲染:
{{ form_start(form) }}
{{ form_widget(form.foo) }}
{{ form_widget(form.bar) }}
{{ form_widget(form.baz) }}
{{ form_end(form) }}
我明白了:
<form>
<select id="form_foo" name="form[foo]">
<option value="0.5">00 h 30</option>
<option value="1">01 h 00</option>
</select>
<select id="form_bar" name="form[bar]">
<option value="0">00 h 30</option>
<option value="1">01 h 00</option>
<option value="2">01 h 30</option>
</select>
<select id="form_baz" name="form[baz]">
<option value="0.5">00 h 30</option>
<option value="1">01 h 00</option>
<option value="2">02 h 00</option>
</select>
</form>
为什么我的bar
渲染没有显示好的值?事实上,每次我使用一个值&gt; 1并且没有舍入到int值,值只是int增量。
答案 0 :(得分:1)
我很惊讶它产生了:
<option value="0">00 h 30</option>
然后
<option value="0.5">00 h 30</option>
用于相同的选项键和值(maybe because of this?)。
负责生成选择列表的类是Symfony/Component/Form/ChoiceList/ArrayChoiceList
所以我在那里解决我的怀疑。
但是,我不知道导致此问题的原因我建议您查看ChoiceType
字段的choice_value
option,因为这决定了每个选项如何转换为值,如果是未指定它仅使用递增的idicies。所以也许尝试使用这个选项,只需将float转换为字符串。
答案 1 :(得分:1)
这是因为array
的密钥必须只是integer
或string
(PHP Manual)。如果提供了浮动键,则PHP会自动将其转换为整数here。让我们看一个例子:
$cache[$choice] = true;
// when $choice = 0.5: $cache = [0 => true]
// when $choice = 1.0: $cache = [0 => true, 1 => true]
然后,当$choice = 1.5
this line(isset($cache[1.5])
)返回true
因为真的检查isset($cache[1])
并且此密钥已经存在,那么castableToString()
会返回false
(检测为重复)并生成选项值,将整数递增为值。
我认为这是一个错误。
目前,请使用choice_value
选项修复该问题:
'choice_value' => function ($value) {
return $value;
}
我在Github上留下了对这个老问题的评论:https://github.com/symfony/symfony/issues/13817#issuecomment-257297132
中修复