如何将数组提交到symfony 4中的未映射表单字段



我试图将带有值的数组提交到symfony 4表单字段,但验证一直失败。

我正在将我的应用程序从symfony 2.7更新为symfony 4。问题是,由于符号形式的更改,我以前使用的表单现在总是无法通过验证。

符号形式具有以下字段

$builder->add('contactData', null, ['mapped' => false])

在symfony 2.7中,我总是在contactData字段中提交一个带有数组值的POST请求,因为它没有映射,所以它只会在提交过程中将数据设置为字段对象,并在处理程序中访问这些值。请求示例:

{
"name": {
"aField": "aValue",
"contactData": {
"something": "value"
}
}
}

然而,在symfony 4中,现在在SymfonyComponentFormForm类中添加了一个验证检查

} elseif (is_array($submittedData) && !$this->config->getCompound() && !$this->config->hasOption('multiple')) {

这导致在向contactData字段提交数据时验证失败,因为submittedData实际上是一个数组。我一直在互联网上寻找并阅读symfony的文档,但我似乎找不到一种方法来诱导与symfony 2.7中相同的行为。

我非常感谢任何建议,我已经在上呆了一段时间了

Symfony已经从v2.7更改为4.0,有很多默认值发生了更改;

我也面临同样的问题,经过两个小时的调查,最后我添加了属性compoundallow_extra_field

所以,这应该能解决你的问题:

$builder->add('contactData', null, [
'mapped' => false,
'compound' => true,
'allow_extra_fields' => true,
])

编辑

这并没有像预期的那样工作,我最终没有出现任何错误,也没有作为提交数据的内容,所以我创建了一个新类型来在预提交事件上动态添加字段,如下所示:

非结构化类型.php

<?php
namespace ASTechSolutionsBundleDynamicFormBundleFormType;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentFormFormEvent;
use SymfonyComponentFormFormEvents;
use SymfonyComponentFormFormInterface;
/**
* Class UnstructuredType.
*
* This class is created to resolve the change of form's behaviour introduced in https://github.com/symfony/symfony/pull/29307
* From v3.4.21, v4.1.10 and v 4.2.2, Symfony requires defining fields and don't accept arrays on a TextType for ex.
* TODO: this is a temporary solution and needs refactoring by declaring explicitly what fields we define, and then accept on requests
*
*/
class UnstructuredType extends AbstractType
{
/**
* {@inheritDoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$this->addChildren($event->getForm(), $event->getData());
});
}
/**
* @param FormInterface $form
* @param $data
*/
public function addChildren(FormInterface $form, $data)
{
if (is_array($data)) {
foreach ($data as $name => $value) {
if (!is_array($value)) {
$form->add($name);
} else {
$form->add($name, null, [
'compound' => true
]);
$this->addChildren($form->get($name), $value);
}
}
} else {
$form->add($data, null, [
'compound' => false,
]);
}
}
}

在另一个答案中不需要@sym183461的UnstructuredType。

信息在额外的字段中。

你定义的字段就像@sym183461说的:

$builder->add('contactData', null, [
'mapped' => false,
'compound' => true,
'allow_extra_fields' => true,
])

然后你可以这样做:

$contactData = $form->get('contactData')->getExtraFields()

你所有的数据都在那里,它能很好地处理深层结构。

最新更新