Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/255.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用Symfony 3/Doctrine的一对多对一属性表单_Php_Postgresql_Symfony_Doctrine Orm_Relational Database - Fatal编程技术网

Php 使用Symfony 3/Doctrine的一对多对一属性表单

Php 使用Symfony 3/Doctrine的一对多对一属性表单,php,postgresql,symfony,doctrine-orm,relational-database,Php,Postgresql,Symfony,Doctrine Orm,Relational Database,问题是: 我有一个三班的模型 人 个人工作 工作 一个人可以有几个工作,任何工作-人关系都可以有“日期开始”属性、“日期结束”和“评论”。因此,我构建了这个模型,其中有一个jointable(person\u job)保存这些属性,并在两个名为person和job的多通属性上建立了关系(通过条令注释生成) 人员属性如下所示: /** * @var string * @ORM\Column(name="name",type="string",length=255,nullable=false)

问题是:

我有一个三班的模型

  • 个人工作
  • 工作
一个人可以有几个工作,任何工作-人关系都可以有“日期开始”属性、“日期结束”和“评论”。因此,我构建了这个模型,其中有一个jointable(person\u job)保存这些属性,并在两个名为person和job的多通属性上建立了关系(通过条令注释生成)

人员属性如下所示:

/**
* @var string
* @ORM\Column(name="name",type="string",length=255,nullable=false)
*/
private $name;

/**
* @var string
* @ORM\Column(name="firstname",type="string",length=255,nullable=true)
*/
private $firstname;
/**
* @var bool
* @ORM\Column(name="active", type="boolean")
*/
private $active;
作业属性如下所示:

/**
* @var string
* @ORM\Column(name="name",type="string",length=255,nullable=false)
*/
private $name;
你的工作是这样的:

/**
* @ORM\ManyToOne(targetEntity="...\Person")
* @ORM\JoinColumn(nullable=false)
*/
private $person;

/**
* @ORM\ManyToOne(targetEntity="...\Job")
* @ORM\JoinColumn(nullable=false)
*/
private $job;

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

/**
* @var \DateTime
* @ORM\Column(name="startdate",type="datetime")
*/
private $datestart;

/**
* @var \DateTime
* @ORM\Column(name="enddate",type="datetime")
*/
private $dateend;
现在,我想为我的“人”创建一个表单,我可以在列表中选择工作,并添加(如果需要)开始日期、结束日期或与此工作相关的注释。我的FormBuilder在“Person”中是这样的:

这是失败的。我的Person类没有“jobs”属性。。那么,我怎样才能做到这些呢?我是否必须添加一个jobs属性,该属性上有一个oneToMany关系,并用“mappedBy”声明

这些学说中的关系仍然让我困惑,我对symfony是新手,我在互联网上查看过,但还没有找到一个合适的解决方案/例子


感谢阅读/帮助

您遇到了Symfony表单最棘手的问题之一。幸运的是,有一些很好的文档。让我总结一下重要的步骤

你是对的:如果你想从一个人的角度操纵这种关系,那么实体人需要知道它与PersonJob的关系。因此,您需要添加一个属性:

// src/AppBundle/Entity/Person.php
/**
 * @ORM\OneToMany(targetEntity="PersonJob", mappedBy="person")
 */
private $personJobs;

public function __construct()
{
    $this->personJobs = new \Doctrine\Common\Collections\ArrayCollection();
}
然后你会有一个表单类型

// src/AppBundle/Form/PersonType.php
$builder
    ->add('name')
    ->add('firstname')
    ->add('personJobs', CollectionType::class, array(
        'entry_type'   => PersonJobType::class,
        'allow_add' => true,
    )
;
注意
personJobs
字段的类型。因为一个人可以有许多PersonJobs,所以您需要一个能够处理集合的表单类型。这是内置
收集类型的用途(签出)。您还需要表单类型
PersonJobType
,以便
CollectionType
知道如何构建子表单:

class PersonJobType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('comment')
            ->add('datestart', DateTimeType::class)
            ->add('dateend', DateTimeType::class)
            ->add('job') // requires Job::__toString() to be defined!
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\PersonJob'
        ));
    }
}
出于调试目的,请将控制器更改为

 public function testAction()
 {
    $person = new Person();
    $form = $this->createForm(PersonType::class, $person);
    $form->add('submit', SubmitType::class);

    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        print '<pre>';
        var_dump($form->getData());
        die();
    }

    return $this->render('default/index.html.twig', [
        'form' => $form->createView(),
    ]);
}
还有两件事要做:

  • 将嵌套的
    PersonJob
    实体的
    person
    属性正确设置为新的(但尚未持久化的)person

  • 通过对新的
    PersonJob
    实体调用
    $em->persist(…)
    来告诉Doctrine有关这些实体的信息

  • 相关文件:

    谢谢你的回答,实际上我已经没有错误了,但我的表格中仍然没有选择工作的“列表”。。。我使用你的代码,我添加“标签”=>“作业”,我只有标签显示。。。表单中没有可用的集合/选择…:你的工作类型是什么样的?(您可能想将其编辑到您的问题中,它可能足够短。)我使用命令行生成它,它只是“$builder->add('person')->add('job')”,这可能是您建议的问题……对不起,我想我误解了您的意思。您应该将选项
    'allow\u add'=>true
    添加到
    personJobs
    字段。当我允许添加时,我得到“可捕获致命错误:类的对象…\Person无法转换为字符串”。。。(createChoiceLabel($choice)函数)
     public function testAction()
     {
        $person = new Person();
        $form = $this->createForm(PersonType::class, $person);
        $form->add('submit', SubmitType::class);
    
        $form->handleRequest($request);
    
        if ($form->isSubmitted() && $form->isValid()) {
            print '<pre>';
            var_dump($form->getData());
            die();
        }
    
        return $this->render('default/index.html.twig', [
            'form' => $form->createView(),
        ]);
    }
    
    object(AppBundle\Entity\Person)#247 (5) {
      ["id":"AppBundle\Entity\Person":private]=>
      NULL
      ["name":"AppBundle\Entity\Person":private]=>
      string(12) "Charles Dude"
      ["firstName":"AppBundle\Entity\Person":private]=>
      string(7) "Charles"
      ["active":"AppBundle\Entity\Person":private]=>
      bool(true)
      ["personJobs":"AppBundle\Entity\Person":private]=>
      object(Doctrine\Common\Collections\ArrayCollection)#248 (1) {
        ["elements":"Doctrine\Common\Collections\ArrayCollection":private]=>
        array(2) {
          [0]=>
          object(AppBundle\Entity\PersonJob)#962 (6) {
            ["id":"AppBundle\Entity\PersonJob":private]=>
            NULL
            ["comment":"AppBundle\Entity\PersonJob":private]=>
            string(19) "Something important"
            ["datestart":"AppBundle\Entity\PersonJob":private]=> 
            object(DateTime)#1088 (3) { … }
            ["dateend": …] => …
            ["person":"AppBundle\Entity\PersonJob":private]=>
            NULL
            ["job":"AppBundle\Entity\PersonJob":private]=>
            object(AppBundle\Entity\Job)#1171 (2) {
              ["id":"AppBundle\Entity\Job":private]=>
              int(2)
              ["name":"AppBundle\Entity\Job":private]=>
              string(5) "Job 2"
            }
          }
          [1]=> …
      }
    }