使用表单集合提交表单时出现 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) {
我有一个员工 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) {