使用表单集合提交表单时出现Symfony2错误 - “警告:spl_object_hash()期望参数1为对象,给定数组”

时间:2015-07-27 17:04:15

标签: php symfony collections doctrine-orm symfony-forms

我有一个与PhoneNumber类有OneToMany关系的Employee类,我正在使用表单构建器,并使用原型通过javascript将多个电话号码嵌入到New Employee表单中。

从转储我的员工变量,我看到每个提交的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';
    }
}

我有什么办法可以解决这个问题吗?有什么我显然做错了吗?

1 个答案:

答案 0 :(得分:1)

解决方案是我不知道的细节 - 在PhoneNumberType类中设置data_class:

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

如果没有这个,处理来自提交表单的数据的代码不知道每个电话号码应该转换为PhoneNumber类,因此它们保持为数组。

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

    public function configureOptions(OptionsResolver $resolver) {