使用表单集合提交表单时出现 Symfony2 错误 - "Warning: spl_object_hash() expects parameter 1 to be object, array given"

Symfony2 error on submitting form with a collection of forms - "Warning: spl_object_hash() expects parameter 1 to be object, array given"

我有一个员工 class,它与 PhoneNumber class 有 OneToMany 关系,我正在使用表单生成器,并使用原型将多个 phone 号码嵌入到新员工表格,javascript.

从转储我的员工变量中,我看到每个提交的 PhoneNumber 都表示为一个数组,而我认为在处理提交的数据时应该将其转换为 PhoneNumber 对象。

我的实体是:

/**
 * Employee
 *
 * @ORM\Table(uniqueConstraints={@UniqueConstraint(name="employee_username_idx", columns={"username"})})
 * @ORM\Entity(repositoryClass="Acme\BambiBundle\Entity\EmployeeRepository")
 */
class Employee
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var array
     *
     * @OneToMany(targetEntity="PhoneNumber", mappedBy="employee", cascade={"persist","remove"}, fetch="EAGER")
     **/
    private $phoneNumbers;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->phoneNumbers = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add phoneNumbers
     *
     * @param \Acme\BambiBundle\Entity\PhoneNumber $phoneNumbers
     * @return Employee
     */
    public function addPhoneNumber(\Acme\BambiBundle\Entity\PhoneNumber $phoneNumbers)
    {
        $phoneNumbers->setEmployee($this);
        $this->phoneNumbers[] = $phoneNumbers;

        return $this;
    }

    /**
     * Remove phoneNumbers
     *
     * @param \Acme\BambiBundle\Entity\PhoneNumber $phoneNumbers
     */
    public function removePhoneNumber(\Acme\BambiBundle\Entity\PhoneNumber $phoneNumbers)
    {
        $this->phoneNumbers->removeElement($phoneNumbers);
    }

    /**
     * Get phoneNumbers
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getPhoneNumbers()
    {
        return $this->phoneNumbers;
    }

    // ...
}

/**
 * PhoneNumber
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class PhoneNumber
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="type", type="text", nullable=true)
     */
    private $type;

    /**
     * @var string
     *
     * @ORM\Column(name="number", type="text")
     */
    private $number;

    /**
     * @var Employee
     *
     * @ManyToOne(targetEntity="Employee", inversedBy="phoneNumbers")
     * @JoinColumn(name="employee_id", referencedColumnName="id", onDelete="CASCADE")
     **/
    private $employee;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set number
     *
     * @param string $number
     * @return PhoneNumber
     */
    public function setNumber($number)
    {
        $this->number = $number;

        return $this;
    }

    /**
     * Get number
     *
     * @return string 
     */
    public function getNumber()
    {
        return $this->number;
    }

    /**
     * Set employee
     *
     * @param \Acme\BambiBundle\Entity\Employee $employee
     * @return PhoneNumber
     */
    public function setEmployee(\Acme\BambiBundle\Entity\Employee $employee = null)
    {
        $this->employee = $employee;

        return $this;
    }

    /**
     * Get employee
     *
     * @return \Acme\BambiBundle\Entity\Employee 
     */
    public function getEmployee()
    {
        return $this->employee;
    }

    /**
     * Set type
     *
     * @param string $type
     * @return PhoneNumber
     */
    public function setType($type)
    {
        $this->type = $type;

        return $this;
    }

    /**
     * Get type
     *
     * @return string 
     */
    public function getType()
    {
        return $this->type;
    }
}

我的表单类型是:

class EmployeeType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
            ->add('phoneNumbers', 'collection', array(
                'type' => new PhoneNumberType(),
                'allow_add' => true,
                'allow_delete' => true,
                'delete_empty' => true,
                'prototype_name' => 'phoneNumberPrototype',
                'by_reference' => false,
            ))
            // ...
            ->add('save', 'submit', array('attr' => array('class' => 'btn btnBlue')));
    }

    public function getName() {
        return 'employee';
    }
}

class PhoneNumberType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
            ->add('type', 'text', array('required' => false, 'label' => 'Type (optional)'))
            ->add('number', 'text');
    }

    public function getName() {
        return 'phoneNumber';
    }
}

有什么我可以尝试解决问题的方法吗?有什么我明显做错的地方吗?

解决方案的细节我不知道 - 在 PhoneNumberType class:

中设置 data_class
    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\BambiBundle\Entity\PhoneNumber',
        ));
    }

如果不这样做,处理提交表单数据的代码就不知道每个 phone 号码都应转换为电话号码 class,因此它们仍然是数组。

请记住我使用的是 Symfony 2.6。在 Symfony 2.7 中,上述函数称为 configureOptions 并且定义略有不同:

    public function configureOptions(OptionsResolver $resolver) {