Symfony:在 属性 路径中给出的类型为“?Doctrine\Common\Collections\Collection”的预期参数,"array"

Symfony: Expected argument of type "?Doctrine\Common\Collections\Collection", "array" given at property path

我有一个名为 DynamicForm 的实体,它看起来像这样:

<?php

namespace App\Entity\Product\DynamicForm;

use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Entity;

/**
 * Class DynamicForm
 * @package App\Entity\Product
 *
 * @Entity
 * @ORM\Table(name="product_dynamic_form")
 */
class DynamicForm
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(name="id", type="integer", unique=true, nullable=false)
     */
    private ?int $id = null;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Product\DynamicForm\Component\Text", mappedBy="dynamicForm")
     * @ORM\JoinColumn(name="component_text_id", referencedColumnName="id")
     */
    private ?Collection $textComponents;

    /**
     * @return Collection|null
     */
    public function getTextComponents(): ?Collection
    {
        return $this->textComponents;
    }

    /**
     * @param Collection|null $textComponents
     *
     * @return DynamicForm
     */
    public function setTextComponents(?Collection $textComponents): DynamicForm
    {
        $this->textComponents = $textComponents;

        return $this;
    }
}

我还为它创建了一个相关类型 - DynamicFormType:

<?php

namespace App\Type\Product\DynamicForm;

use App\Entity\Product\DynamicForm\DynamicForm;
use App\Type\Product\DynamicForm\Component\TextType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class DynamicFormType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('textComponents', CollectionType::class, [
                'entry_type'    => TextType::class,
                'entry_options' => ['label' => false],
                'allow_add'     => true,
                'allow_delete'  => true,
                'label'         => ' '
            ])
            ->add('submit', SubmitType::class, [
                'label' => 'form.basic.save'
            ]);
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefault('data_class', DynamicForm::class);
    }
}

来自命名空间 App\Type\Product\DynamicForm\Component\TextType 的 TextType 条目类型 class 如下所示:

<?php

namespace App\Type\Product\DynamicForm\Component;

use App\Entity\Product\DynamicForm\Component\Text;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type as FormType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Contracts\Translation\TranslatorInterface;

class TextType extends AbstractType
{
    private TranslatorInterface $translator;

    /**
     * TextType constructor.
     *
     * @param TranslatorInterface $translator
     */
    public function __construct(TranslatorInterface $translator)
    {
        $this->translator = $translator;
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('label', FormType\TextType::class, [
                'required'           => true,
                'translation_domain' => 'wedding',
                'label'              => 'setting.form.dynamic_by_user.query_to_guest'
            ])
            ->add('type', FormType\ChoiceType::class, [
                'required'                  => true,
                'translation_domain'        => 'wedding',
                'label'                     => 'setting.form.dynamic_by_user.select_type',
                'attr'                      => [
                    'class'                       => 'enriched',
                    'data-search-placeholder'     => $this->translator->trans('select.search'),
                    'data-search-no-results-text' => $this->translator->trans('select.search_no_results_found')
                ],
                'choice_translation_domain' => 'wedding',
                'choices'                   => [
                    'setting.form.dynamic_by_user.type_text'     => Text::TYPE_TEXT_FIELD,
                    'setting.form.dynamic_by_user.type_textarea' => Text::TYPE_TEXT_AREA,
                    'setting.form.dynamic_by_user.type_email'    => Text::TYPE_EMAIL_FIELD,
                    'setting.form.dynamic_by_user.type_number'   => Text::TYPE_NUMBER_FIELD,
                ]
            ]);
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefault('data_class', Text::class);
    }
}

当我尝试传输表单时,控制器中的请求包含表单数据,如您所见,在以下屏幕截图中:

我现在的问题是我总是收到以下错误(在通过 ->handleRequest($request) 在控制器中创建的表单上处理表单请求时):

Expected argument of type "?Doctrine\Common\Collections\Collection", "array" given at property path "textComponents".

我在其他 classes 中也有这样的收集设置,但没有问题 - 我不知道更多,任何人都可以帮助我或看到错误吗?

(我正在使用 Symfony 版本 5.2.9,如果您需要任何进一步的信息,请提出要求 - 我会尽快给您)

正在尝试在您的实体中添加构造函数

public function __construct()
{
    $this->textComponents = new ArrayCollection();
}

添加 addTextComponentremoveTextComponent 方法而不是 setTextComponents

public function addTextComponent(Text $textComponent): self
{
    $textComponent->setDynamicForm($this);
    $this->textComponents->add($textComponent);

    return $this;
}

public function removeTextComponent(Text $textComponent): self
{
    $this->textComponents->removeElement($textComponent);

    return $this;
}

在 textComponents 表单参数中添加 'by_reference' => false

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('textComponents', CollectionType::class, [
            'entry_type'    => TextType::class,
            'entry_options' => ['label' => false],
            'allow_add'     => true,
            'allow_delete'  => true,
            'label'         => ' ',
            'by_reference'  => false,
        ])
        ->add('submit', SubmitType::class, [
            'label' => 'form.basic.save'
        ]);
}

我可以通过这样做来解决这个问题,它允许我们传递一个集合或一个空数组,或者我认为是文本的实体数组:

/**
     * @param Collection|Text[] $textComponents
     *
     * @return DynamicForm
     */
    public function setTextComponents($textComponents): DynamicForm
    {
        $this->textComponents = $textComponents;

        return $this;
    }