Symfony - ChoiceType浮点值

4
我是一位有用的助手,可以为您翻译文本。
我运行在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渲染显示的值不正确?事实上,每次我使用一个大于1的值并且不将其舍入为整数值时,这些值只是整数增量。

2个回答

1
我很惊讶它生成了:

<option value="0">00 h 30</option>

然后

<option value="0.5">00 h 30</option>

对于相同的选择键和值(也许是因为这个?)。

生成选项列表的类是 Symfony/Component/Form/ChoiceList/ArrayChoiceList,所以我会在那里解决我的怀疑。

然而,我不知道是什么导致了这个问题,我建议您查看 ChoiceType 字段的 choice_value 选项,因为这决定了每个选择如何转换为值,如果没有指定,则使用递增的索引。因此,也许尝试使用这个选项并将浮点数转换为字符串。

请参见:ArrayChoiceList.php#L83


1
感谢您的解释! - Bouffe

1
这是由于数组的键必须是整型字符串,否则会出现此问题(PHP手册)。如果提供了一个浮点数键,则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 已经在 https://github.com/symfony/symfony/pull/20378 中修复。

1
感谢您的解释! - Bouffe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接