Doctrine orm 条令2:表单字段显示条令\公共\集合\ArrayCollection@00作为价值

Doctrine orm 条令2:表单字段显示条令\公共\集合\ArrayCollection@00作为价值,doctrine-orm,zend-framework2,doctrine,zend-form2,Doctrine Orm,Zend Framework2,Doctrine,Zend Form2,我对Zend Framework 2和Doctrine 2非常陌生,所以我甚至不知道如何搜索或调试我的问题 我有3个数据库表 1。广告 id 广告名称 2。类别 id 分类名 3。广告类别 广告id 类别识别码 我已经创建了两个实体,广告和类别。我现在有了一个表格,可以显示可供选择的类别。我使用jQuery将类别显示为一个列表,而不是下拉列表,以及一个可选函数。因此,当您单击某个类别时,此listelement的值将输入到名为categories的隐藏输入字段中 一切正常,除了显示表单时,隐

我对Zend Framework 2和Doctrine 2非常陌生,所以我甚至不知道如何搜索或调试我的问题

我有3个数据库表

1。广告
id
广告名称

2。类别
id
分类名

3。广告类别
广告id
类别识别码

我已经创建了两个实体,广告和类别。我现在有了一个表格,可以显示可供选择的类别。我使用jQuery将类别显示为一个列表,而不是下拉列表,以及一个可选函数。因此,当您单击某个类别时,此listelement的值将输入到名为categories的隐藏输入字段中

一切正常,除了显示表单时,隐藏类别输入字段的值为Doctrine\Common\Collections\ArrayCollection@000000000.....而不是空的。我做错了什么?我试图找到一个解决办法,但没有成功

我选择了多个关系,因为我希望最终能够保存多个类别。目前它只与1一起工作,但通过这种方式,我应该能够在以后更改它

这里是我的广告实体:

namespace Advert\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use DateTime;

/** Advert
 * 
 * @ORM\Table(name="advert")
 * @ORM\Entity(repositoryClass="Advert\Repository\AdvertRepository")
 */

class Advert
{
 /**
  * @var integer
  *
  * @ORM\Column(name="id", type="integer", nullable=false)
  * @ORM\Id
  * @ORM\GeneratedValue(strategy="IDENTITY")
  */
  private $id;


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

 /** 
  * @ORM\ManyToMany(targetEntity="Category", inversedBy="adverts", cascade={"persist"}) 
  * @ORM\JoinTable(name="advert2category") 
  */
  private $categories;

  public function __construct() 
  { 
    $this->categories = new ArrayCollection();
  }

 /**
  * Set categories
  *
  * @param ArrayCollection $category
  * @return Advert
  */
  public function setCategories($categories)
  {
    $this->categories = $categories;
    return $this;
  }


 /**
  * Get categories
  *
  * @return ArrayCollection
  */
  public function getCategories()
  {
    return $this->categories;
  }

  /**
   * @param Collection $categories
   */
  public function addCategories($categories)
  {
    foreach ($categories as $category) {
        $this->categories->add($category);
    }
  }

  /**
   * @param Collection $categories
   */
  public function removeCategories($categories)
  {
    foreach($categories as $category){
        $this->categories->removeElement($category);
    }

  }
广告实体中是否存在导致此问题的错误?我希望有人能帮忙。我有这个问题,因为几个星期,不能让它正常工作

更新--将我的表单和控制器中的部件添加到调用表单中

下表显示2个下拉元素和2个隐藏输入字段。这两个下拉字段通过jQuery变成一个可选列表。单击Maincategory中的列表元素时,所选Maincategory的子类别将再次显示为可选列表。然后将MaincategoryID输入隐藏的categoryID字段。从列表中选择子类别后,该类别的id将写入“隐藏类别”字段。点击“下一步”按钮,将$u POST['categories']的值与广告ID一起保存在我的链接表中

use Zend\Form\Form;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;

class CategoryForm extends Form implements ObjectManagerAwareInterface
{

protected $objectManager;


public function __construct()
{       
    $this->setInputFilter(new AdvertFilter());
    parent::__construct('category');


}

public function init()
{
    $this->setAttribute('method', 'post');




    $this->add(array(
            'name' => 'categories',
            'attributes' => array(
                    'type' => 'hidden',
                    'id'    => 'categories',

            ),
            'options'=> array(
                    'label'=> 'categories',
                    ),


    ));


    $this->add(
            array(

                    'type' => 'DoctrineModule\Form\Element\ObjectSelect',
                    'name' => 'categoriesList',

                    'options' => array(

                            'object_manager' => $this->getObjectManager(),
                            'label' => 'Main Category',
                            'target_class'   => 'Advert\Entity\Category',
                            'property'       => 'name',
                            'is_method' => true,

                            'find_method'        => array(
                                    'name'   => 'getMainCategories',
                            ),
                    ),
                    'allow_empty'  => true,
                    'required'     => false,
                    'attributes' => array(
                            'id' => 'categoryList',
                            'multiple' => true,


                    )
            )
    );

    $this->add(
            array(
                    'type' => 'DoctrineModule\Form\Element\ObjectSelect',
                    'name' => 'subcategoryList',
                    'options' => array(
                            'object_manager' => $this->getObjectManager(),
                            'label' => 'Sub Category',


                            'target_class'   => 'Advert\Entity\Category',
                            'property'       => 'name',

                            'is_method' => true,
                            'find_method'        => array(
                                    'name'   => 'getSubCategories',
                            ),
                    ),
                    'allow_empty'  => true,
                    'required'     => false,
                    'attributes' => array(

                            'id' => 'subcategoryList',
                            'multiple' => true,
                            )
            )
    );


    $this->add(array(
            'type' => 'hidden',
            'name' => 'categoryID',
            'options'=> array(
                    'label'=> 'categoryID'),
            'attributes' => array(
                    'id' => 'categoryID',
                    'value' => '1',
            )
    ));

   $this->add(array(
            'name' => 'submit',
            'attributes' => array(
                    'type'  => 'submit',
                    'value' => 'Next',
                    'id' => 'submitbutton',
            ),
    ));



}

public function setObjectManager(ObjectManager $objectManager)
{
    $this->objectManager = $objectManager;
}

public function getObjectManager()
{
    return $this->objectManager;
}

}
在控制器中,我按以下方式调用表单:

    $sl = $this->getServiceLocator();
    $form = $sl->get('FormElementManager')->get('\Advert\Form\CreateForm');

    # create a new, empty entity
    $advert = new Advert();

    # set the hydrator to connect form and entity
    $form->setHydrator(new DoctrineHydrator($this->getEntityManager(),'Advert\Entity\Advert'));

    # connect form and entity
    $form->bind($advert);

首先,双向关系不使用联接表。您的映射似乎是双向的,但是您尝试使用第三个表:
advert\u category

我建议将
广告
实体的
$categories
属性映射更改为单向关系:

class Advert
{
     // ...

    /**
     * @ORM\ManyToMany(targetEntity="Category")
     * @ORM\JoinTable(name="advert_category",
     *      joinColumns={@ORM\JoinColumn(name="advert_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")}
     *      )
     **/
    protected $categories;

    // ...
}
此外,如果您想利用
Advert
实体中的
addCategories(Collection$categories)
removeCategories(Collection$categories)
方法,您还应该实现。(我假设您正在使用)

此时,您的
Category
实体不应该知道任何有关
Advert
的信息,并且您不能通过
$Category->getAdverts()等实体方法直接从类别实例访问所有广告。但是,当需要时,您可以在您的AdvertRepository中轻松编写
getAdvertsByCategoryId($categoryId)
方法

最后一个细节是,您应该有一个
CategoryFieldset
(它还需要使用
Category
实体作为对象),并且您必须使用
target\u元素
配置键或直接提供实例本身将此字段集指向表单的
categories
元素

例如:

$formManager = $serviceLocator->get('FormElementManager');
$form = $formManager->get('your\form\name');
$form->add(
    array(
        'name' => 'categories',
        'type' => 'Zend\Form\Element\Collection',
        'options' => array(
            'target_element' => $formManager->get('your\fieldset\name');
            // or you can do this but probably you will also need $entityManager
            // inside the CategoryFieldset
            // 'target_element' => new CategoryFieldset();
            ),
        )
    );
我强烈建议使用
FormElementManager
获取表单和字段集实例,并通过
new AdvertForm()
new CategoryFieldset()
直接实例化它们。另外,编写一个
AbstractFormElementFactory
$entityManager
类依赖项以正确的方式注入到您的字段集和表单中是一个很好的实践


希望能有所帮助。

感谢foozy提供的详细答案。addCategories和removecategories已经包括在内了,我只是把它从上面漏掉了,因为我认为这对我的问题不重要,它现在显示出来了。我很惊讶双向关系没有使用联接表,因为我在网上到处都看到了这种情况,我将详细介绍。我现在已经把我的表格也添加到了帖子中,所以我想错误在这里,但我看不到在哪里。也许你看到了?我将尝试理解您的建议并进行更改。我肯定会将类别字段集分离为单个类。不需要在
AdvertForm
中引入“categoryID”隐藏元素,因为在category字段集中将有一个
id
元素,并且AdvertForm应该有一个
categories
集合。我认为子类别问题也需要在Category字段集中处理,而不是以广告形式处理。