开始使用symfony2。到目前为止我很喜欢。我尝试了一个多实体的形式来弄清楚,如果形式构建器是可用于我的需要。首先是我的实体:
客户实体 namespace CustomerBundle'Entity;
use Doctrine'Common'Collections'ArrayCollection;
use Symfony'Component'DependencyInjection'ContainerInterface;
use Doctrine'ORM'Mapping as ORM;
use UserBundle'Entity'Users;
/**
* @ORM'Table(name="customers")
* @ORM'HasLifecycleCallbacks
* @ORM'Entity(repositoryClass="CustomerBundle'Entity'CustomerRepository")
*/
class Customer
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @ORM'Id
* @ORM'Column(name="id", type="integer", nullable=false)
* @ORM'GeneratedValue(strategy="IDENTITY")
*/
protected $Id;
/**
* @ORM'Column(name="nickname", type="string", length=50, unique=true)
*/
protected $NickName;
/**
* @ORM'OneToMany(targetEntity="'CustomerBundle'Entity'Address", mappedBy="Customer")
**/
protected $Addresses;
/**
* @ORM'OneToMany(targetEntity="'CustomerBundle'Entity'Mail", mappedBy="Customer")
**/
protected $Emails;
/**
* @ORM'ManyToMany(targetEntity="'UserBundle'Entity'Users")
* @ORM'JoinTable(name="customers_mapping_users",
* joinColumns={@ORM'JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM'JoinColumn(name="customer_id", referencedColumnName="id")}
* )
**/
protected $Users;
/**
* @ORM'Column(name="lead_type", type="string", length=50, nullable=true)
*/
protected $LeadType;
/**
* @ORM'ManyToOne(targetEntity="'UserBundle'Entity'Users", fetch="EXTRA_LAZY")
* @ORM'JoinColumn(name="lead__owner_user_id", referencedColumnName="id")
*/
protected $LeadOwner;
/**
* @ORM'OneToMany(targetEntity="'CustomerBundle'Entity'Note", mappedBy="Customer")
**/
protected $Notes;
protected $Reminders;
protected $SupportTickets;
protected $Invoices;
protected $Documents;
/**
* @ORM'OneToMany(targetEntity="'CustomerBundle'Entity'Todo", mappedBy="Customer")
**/
protected $Todos;
/**
* @return Todo[]
*/
public function getTodos()
{
return $this->Todos;
}
/**
* @param Todo $todo
*/
public function addTodo(Todo $todo)
{
$this->Todos->add($todo);
}
/**
* @param Todo $todo
*
* @return bool
*/
public function hasTodo(Todo $todo=null)
{
return $this->Todos->contains($todo);
}
/**
* @param Todo $todo
*
* @return $this
*/
public function removeTodo(Todo $todo)
{
$this->Todos->removeElement($todo);
return $this;
}
}
我的地址实体
<?php
namespace CustomerBundle'Entity;
use Symfony'Component'DependencyInjection'ContainerInterface;
use Doctrine'ORM'Mapping as ORM;
/**
* @ORM'Table(name="customers_address")
* @ORM'HasLifecycleCallbacks
* @ORM'Entity(repositoryClass="CustomerBundle'Entity'AddressRepository")
*/
class Address
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @ORM'Id
* @ORM'Column(name="id", type="integer", nullable=false)
* @ORM'GeneratedValue(strategy="IDENTITY")
*/
protected $Id;
/**
* @ORM'ManyToOne(targetEntity="CustomerBundle'Entity'Customer", inversedBy="Addresses")
* @ORM'JoinColumn(name="customer_id", referencedColumnName="id")
**/
protected $Customer;
/**
* @ORM'Column(name="first_name", type="string", length=50, nullable=true)
*/
protected $FirstName;
/**
* @ORM'Column(name="last_name", type="string", length=50, nullable=true)
*/
protected $LastName;
/**
* @ORM'Column(name="company_name", type="string", length=50, nullable=true)
*/
protected $CompanyName;
/**
* @ORM'Column(name="street1", type="string", length=250, nullable=true)
*/
protected $Street1;
/**
* @ORM'Column(name="street2", type="string", length=250, nullable=true)
*/
protected $Street2;
/**
* @ORM'Column(name="street3", type="string", length=250, nullable=true)
*/
protected $Street3;
/**
* @ORM'Column(name="zipcode", type="string", length=10, nullable=true)
*/
protected $Zipcode;
/**
* @ORM'Column(name="city", type="string", length=50, nullable=true)
*/
protected $City;
/**
* @ORM'Column(name="country", type="string", length=50, nullable=true)
*/
protected $Country;
/**
* @ORM'Column(name="phone", type="string", length=50, nullable=true)
*/
protected $Phone;
/**
* @ORM'Column(name="fax", type="string", length=50, nullable=true)
*/
protected $Fax;
/**
* @ORM'Column(name="tax_id", type="string", length=50, nullable=true)
*/
protected $TaxId;
}
最后但同样重要的是
namespace CustomerBundle'Entity;
use HomeBundle'Traits'CreateTrait;
use HomeBundle'Traits'serializeTrait;
use HomeBundle'Traits'UpdateTrait;
use Symfony'Component'DependencyInjection'ContainerInterface;
use Doctrine'ORM'Mapping as ORM;
/**
* @ORM'Table(name="customer_mail")
* @ORM'HasLifecycleCallbacks
* @ORM'Entity(repositoryClass="CustomerBundle'Entity'MailRepository")
*/
class Mail
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @ORM'Id
* @ORM'Column(name="id", type="integer", nullable=false)
* @ORM'GeneratedValue(strategy="IDENTITY")
*/
protected $Id;
/**
* @ORM'Column(name="email", type="string", length=255, unique=true)
*/
protected $Email;
/**
* @ORM'ManyToOne(targetEntity="CustomerBundle'Entity'Customer", inversedBy="Emails")
* @ORM'JoinColumn(name="customer_id", referencedColumnName="id")
**/
protected $Customer;
}
根据http://symfony.com/doc/current/cookbook/form/form_collections.html我添加了三种表单类型:
地址:
use Symfony'Component'Form'AbstractType;
use Symfony'Component'Form'FormBuilderInterface;
use Symfony'Component'OptionsResolver'OptionsResolver;
class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('FirstName','text',array('label'=>'firstname'))
->add('LastName','text',array('label'=>'lastname'))
->add('CompanyName','text',array('label'=>'company name'))
->add('Street1','text',array('label'=>'street 1'))
->add('Street2','text',array('label'=>'street 2'))
->add('Street3','text',array('label'=>'street 3'))
->add('Zipcode','text',array('label'=>'zip code'))
->add('City','text',array('label'=>'city'))
->add('Country','text',array('label'=>'country'))
->add('Phone','text',array('label'=>'phone'))
->add('Fax','text',array('label'=>'fax'))
->add('TaxId','text',array('label'=>'taxid'));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'CustomerBundle'Entity'Address',
)
);
}
public function getName()
{
return 'address';
}
}
邮件: use Symfony'Component'Form'AbstractType;
use Symfony'Component'Form'FormBuilderInterface;
use Symfony'Component'OptionsResolver'OptionsResolver;
class MailType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('Email','email',array('label'=>'email'));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'CustomerBundle'Entity'Mail',
)
);
}
public function getName()
{
return 'mail';
}
}
和客户作为顶级实例:
<?php
namespace CustomerBundle'Form'Type;
use Symfony'Component'Form'AbstractType;
use Symfony'Component'Form'FormBuilderInterface;
use Symfony'Component'OptionsResolver'OptionsResolver;
class CustomerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('NickName','text',array('label'=>'customers nickname'))
->add('address','collection',array('type'=>new AddressType()))
->add('mail','collection',array('type'=>new MailType()));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'CustomerBundle'Entity'Customer',
)
);
}
public function getName()
{
return 'customer';
}
}
在My Controller的create action中,我添加了这个:
/**
* @Route("/Customers/Create", name="crm_customers_create")
* @Template()
*/
public function createAction()
{
$customer = new Customer();
$address = new Address();
$mail = new Mail();
$customer->addAddress($address);
$customer->addEmail($mail);
$form = $this->createForm(new CustomerType(),$customer);
return array(
'form'=>$form->createView(),
);
}
和我的小树枝模板包含:
{% extends "HomeBundle:Core:base.html。树枝"%}
{% block title %}CustomerBundle:Customers:create{% endblock %}
{% block body %}
<div class="col-xs-10 col-xs-offset-1">
<fieldset>
<legend>{% trans %}create a new Customer{% endtrans %}</legend>
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
</fieldset>
</div>
{% endblock %}
所以当我打开页面时,我只得到这个输出:
预期参数类型为"array or ('Traversable and 'ArrayAccess)", "boolean"给定500内部服务器错误-意外类型异常堆栈跟踪
in vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php at line 84 -
}
if (!is_array($data) && !($data instanceof 'Traversable && $data instanceof 'ArrayAccess)) {
throw new UnexpectedTypeException($data, 'array or ('Traversable and 'ArrayAccess)');
}
// First remove all rows
at ResizeFormListener ->preSetData (object(FormEvent), 'form.pre_set_data', object(EventDispatcher))
at call_user_func (array(object(ResizeFormListener), 'preSetData'), object(FormEvent), 'form.pre_set_data', object(EventDispatcher))
in app/cache/dev/classes.php at line 1826 +
at EventDispatcher ->doDispatch (array(array(object(ResizeFormListener), 'preSetData')), 'form.pre_set_data', object(FormEvent))
in app/cache/dev/classes.php at line 1759 +
at EventDispatcher ->dispatch ('form.pre_set_data', object(FormEvent))
in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php at line 43 +
at ImmutableEventDispatcher ->dispatch ('form.pre_set_data', object(FormEvent))
in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 342 +
at Form ->setData (false)
in vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php at line 57 +
at PropertyPathMapper ->mapDataToForms (object(Customer), object(RecursiveIteratorIterator))
in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 396 +
at Form ->setData (object(Customer))
in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 488 +
at Form ->initialize ()
in vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php at line 226 +
at FormBuilder ->getForm ()
in vendor/symfony/symfony/src/Symfony/Component/Form/FormFactory.php at line 39 +
at FormFactory ->create (object(CustomerType), object(Customer), array())
in vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php at line 250 +
at Controller ->createForm (object(CustomerType), object(Customer))
in src/CustomerBundle/Controller/CustomersController.php at line 47 +
at CustomersController ->createAction ()
at call_user_func_array (array(object(CustomersController), 'createAction'), array())
in app/bootstrap.php.cache at line 3109 +
at HttpKernel ->handleRaw (object(Request), '1')
in app/bootstrap.php.cache at line 3071 +
at HttpKernel ->handle (object(Request), '1', true)
in app/bootstrap.php.cache at line 3222 +
at ContainerAwareHttpKernel ->handle (object(Request), '1', true)
in app/bootstrap.php.cache at line 2444 +
at Kernel ->handle (object(Request))
in web/app_dev.php at line 29 +
我不知道问题是从哪里来的,因为我看不出是哪个实体导致了故障。到目前为止一切看起来都很好。我还试图只访问其中一个表单字段,但这导致了同样的异常。如果您能帮助我解决这个问题,我将不胜感激。
表单字段名必须匹配实体属性名。CustomerType
表单字段address
和email
与Customer
实体属性Addresses
和Emails
不匹配