Symfony 表单只读字段

Posted

技术标签:

【中文标题】Symfony 表单只读字段【英文标题】:Symfony form read only field 【发布时间】:2012-10-20 22:56:54 【问题描述】:

我应该如何使用 Symfony 表单组件呈现 read-only 字段?

这就是我试图这样做无济于事的方式:

Symfony 2

$builder
    ->add('descripcion', 'text', array(
        'read_only' =>'true'
    ));

Symfony 3

$builder
    ->add('descripcion', TextType::class, array(
        'read_only' => 'true'
    ));

【问题讨论】:

如果答案是解决此问题的解决方案,请标记为已接受:) 【参考方案1】:

Symfony 3 上提供的答案都以这个例外结束:

未捕获的 php 异常 Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException: "选项 "read_only" 不存在。

正确的做法是利用字段上的attr 属性:

->add('descripcion', TextareaType::class, array(
    'attr' => array(
        'readonly' => true,
    ),
));

如果您希望在表单提交期间有一个数据未发布到服务器的字段,您应该使用disabled,例如:

->add('field', TextareaType::class, array(
    'disabled' => true,
));

在您的表单构建器对象上。

【讨论】:

投反对票,因为此方法将设置 html 属性,但如果请求包含 descripcion 的新值,表单仍将接受它。所以它给了作者一种虚假的安全感。 感谢您的反对,但 ReadOnly,注释 html 表单字段的客户端功能不是 security 的事情。你必须在服务器端处理你security。如果您对 Symfony 有疑问,您可以访问他们的 Github 帐户并在那里提交问题。 @Trix 我认为 user2045006 意味着使用您的解决方案,任何用户都可以手动更改 html 中的属性并发布字段,并且表单将自动更新实体。使用表单的只读选项将确保即使用户更改 html 实体也不会更新,因此更安全。 此 HTML 表单行为是设计使然。用户应该能够改变任何东西,客户端。您可以在服务器端审核和控制一切。这称为网络。 @Pmpr Symfony 提供了一种通过在客户端禁用字段编辑和在服务器端添加安全防护来使字段只读的方法。检查disabled option。虽然 OP 只询问如何渲染只读字段,但他/她很可能是指如何处理双方的只读字段。这就是为什么我同意 Courtney Miles 建议不要只使用只读 HTML 属性的原因。【参考方案2】:

readonly 而不是read_only。你应该像这样在attr 中设置这个选项:

->add('', TextType::class, array('attr'=> array('readonly' => true)))

【讨论】:

【参考方案3】:

建议使用 disabled 选项,因为根据文档,任何提交的值都将被忽略:https://symfony.com/doc/current/reference/forms/types/text.html#disabled

$builder->add('descripcion', TextType::class, [
    'disabled' => 'true',
]);

【讨论】:

有一个主要区别:“是的,我想要这个字段,但它的值不能改变”和“我不想要这个字段”【参考方案4】:

对于禁用的实体类型字段可以正常工作

->add('organizacion', EntityType::class, array(
    'class' => 'AppBundle:Organizacion',
    'label' => 'Institución/Organización',
    'choice_label' => 'nombre',
    'disabled' => true
))

【讨论】:

【参考方案5】:

Symfony 4 只允许在表单域中使用“禁用”选项。但它与“只读”不同。

已禁用 - 用户无法编辑字段,并且在表单提交期间未传递其值。 只读 - 用户无法编辑字段,但其值在表单提交期间被传递。

我为“只读”找到的唯一解决方案是:

->add('fieldname', TextType::class, [
            'label' => false,
            'attr'=> [ 'readonly' => true ]
        ])

【讨论】:

【参考方案6】:

只有“禁用”选项不会导致错误

$builder
    ->add('descripcion', TextType::class, array(
        'disabled' => 'true'
    ));

【讨论】:

【参考方案7】:

其他解决方案可能是:

->add('value', TextType::class, ['disabled' => true]):

取自:http://symfony.com/doc/current/reference/forms/types/text.html#disabled

【讨论】:

【参考方案8】:

我认为,将表单字段呈现为只读并防止表单接受请求中的新值的唯一安全方法如下。

$builder->add(
    'description',
    TextType::class,
    ['disabled' => true]
);

使用['attr' => ['readonly' => true]]['attr' => ['disabled' => true]] 的另一个建议会使您容易受到伪造请求的攻击。

后两个选项都会在字段上设置readonlydisabled 属性,但如果请求中包含该字段,您的表单仍将接受该字段的新值。

只有上面的第一个选项既会禁用表单字段,也会阻止您的表单接受请求中字段的新值。

我已经用 Symfony Form 3.4 对此进行了测试。我不知道 4 的行为是否相同。

【讨论】:

是的,Symfony 4 的行为是一样的。 好答案。 Symfony 5 也可以工作。【参考方案9】:

让我添加一些其他答案无助于管理的内容。在许多情况下,作为字段处理但“调整”以禁用版本可能会起作用。但是,至少很难以完全阻止编辑的某些格式呈现(即呈现为标签)。

如何解决这个问题?我所做的是将字段定义为 HiddenType,并在模板中使用 form.vars.value.myfield item.myfield 进行渲染,将“item”作为实体对象,包含在您能想到的任何内容中,就像任何其他 HTML 元素一样。

【讨论】:

【参考方案10】:

更新:从 Symfony 3.0 开始,readonly 值应该在 attr 选项中设置。 http://symfony.com/doc/2.8/reference/forms/types/form.html#read-only

也可以使用 disabled 选项。

【讨论】:

"disabled" 和 "readonly" 不是一回事,不能互换使用!!!虽然它们都以类似的方式呈现给用户,但只读字段将成为帖子的一部分,而禁用的字段则不会。【参考方案11】:

read_only 自 Symfony 2.8 起已弃用。所以请改用readonly。并为此属性提供布尔值

->add('','text',array('readonly' => true))

【讨论】:

【参考方案12】:

您已将只读属性声明为字符串,它必须是布尔值。

删除true周围的引号

像这样:

->add('descripcion','text',array('read_only' => true))

true,不带引号。

【讨论】:

【参考方案13】:

如果 familia 和proveedor 是与其他实体的关系,我认为它们不应该是文本类型。尝试使他们的类型无效或更改为 entity 类型并检查它是否有效。

【讨论】:

以上是关于Symfony 表单只读字段的主要内容,如果未能解决你的问题,请参考以下文章

Symfony 表单验证:如果另一个字段不为空,则需要字段

带有文件类型字段editAction的Symfony 3表单集合实体

Symfony:如何处理表单中的日期字段

Symfony2 复合表单,将错误与字段关联

预填充 EntityType 类型的 Symfony 表单的字段

Symfony 2表单字段收音机需要=假?