将表单与表单集合绑定到ZF2中的实体

时间:2014-12-11 00:17:39

标签: php forms zend-framework2

我设置了一个基本的概念证明,涉及音乐家和专辑,用于在Zend Framework中将表单与表单集合绑定。

这是音乐家班:

<?php

namespace Application\Entity;


class Musician {

protected $name;

protected $albums;

public function setName($name)
{
    $this->name = $name;
    return $this;
}
public function getName()
{
    return $this->name;
} 
public function setAlbums($album)
{
   $this->album = $album;
   return $this;
}
public function getAlbums()
{
    return $this->albums;
}

以下是专辑类:

<?php

namespace Application\Entity;


class Album {

protected $name;

protected $releaseYear;

public function setName($name)
{
    $this->name = $name;
    return $this;
}
public function getName()
{
    return $this->name;

}
public function setReleaseYear($releaseYear)
{
   $this->releaseYear = $releaseYear;
   return $this;
}
public function getReleaseYear()
{
    return $this->releaseYear;

}

}

专辑Fieldset:

专辑字段集:

<?php

namespace Application\Form\Music;

use Zend\Form\Fieldset;
use Zend\Stdlib\Hydrator\ClassMethods;
use Zend\Validator; 
use Zend\Form\Element;
use Application\Entity\Album;

use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\InputFilter\InputFilterProviderInterface;

class AlbumFieldSet extends Fieldset implements  InputFilterProviderInterface,         ServiceLocatorAwareInterface
{


   public function __construct()
   {
   parent::__construct('album');

   $this->setObject(new Album());
   $this->setHydrator(new ClassMethods());


   $this->add(array(
       'type' => 'Text',
       'name' => 'name',
       'options' => [
       ]
   ));

   $this->add(array(
       'type' => 'Text',
       'name' => 'releaseYear',
       'options' => [
       ]
   ));



  }

   public function init()
   {

   } 




   /**
    * Should return an array specification compatible with
    * {@link Zend\InputFilter\Factory::createInputFilter()}.
    *
    * @return array
    */
   public function getInputFilterSpecification()
   {
   return [
       'name' => array(
           'required' => true,
           'validators' => array(
           )
       ),
   ];
 }

  /**
   * Set service locator
   *
   * @param ServiceLocatorInterface $serviceLocator
   */
  public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
  {
      $this->sl = $serviceLocator;
  }

  /**
   * Get service locator
   *
   * @return ServiceLocatorInterface
   */
  public function getServiceLocator()
  {
      return $this->sl;
  }

}

这是音乐家表格

<?php

namespace Application\Form\Music;

use Application\Entity\Album;
use Zend\Form\Form;
use Zend\Form\Element\Collection;
use Zend\Stdlib\Hydrator\ClassMethods;
use Zend\Stdlib\Hydrator\ObjectProperty;
use Zend\Validator;
use Zend\Form\Element;
use Application\Form\Music\AlbumFieldset;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\InputFilter\InputFilterProviderInterface;

class MusicianForm extends Form implements  InputFilterProviderInterface, ServiceLocatorAwareInterface
{


   public function __construct()
   {

       parent::__construct('');

   }

   public function init()
   {

   }



   public function setMusician($musician) {

       $this->setHydrator(new ClassMethods());
       $this->add(array(
           'type' => 'Text',
           'name' => 'name',
           'options' => [
           ]
       ));




       $this->buildFields();
       $this->bind($musician);

   }


   public function buildFields() {


       $fs = new AlbumFieldSet();
       $fs->setHydrator(new ObjectProperty());
       $fs->setObject(new Album());

       $this->add(array(
           'type' => 'Zend\Form\Element\Collection',
           'name' => 'albums',
           'options' => array(
               'label' => 'Form Values',
               'count' => 2,
               'allow_add' => false,
               'allow_remove' => false,
               'should_create_template' => false,
               'target_element' => $fs,
               'use_as_base_fieldset' => true,
           ),
       ));

   }



   /**
    * Should return an array specification compatible with
    * {@link Zend\InputFilter\Factory::createInputFilter()}.
    *
    * @return array
    */
   public function getInputFilterSpecification()
   {
       return [
           'name' => array(
               'required' => true,
               'validators' => array(
               )
           ),
       ];
   }

   /**
    * Set service locator
    *
    * @param ServiceLocatorInterface $serviceLocator
    */
   public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
   {
       $this->sl = $serviceLocator;
   }

   /**
    * Get service locator
    *
    * @return ServiceLocatorInterface
    */
   public function getServiceLocator()
   {
       return $this->sl;
   }

}

控制器代码:

<?php

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Application\Entity\Musician as Musician;
use Application\Entity\Album as Album;


class MusiciansController extends AbstractActionController
{

   public function createMusicianAction()
   {


       $musician = new Musician();
       $albumOne = new Album();
       $albumTwo = new Album();
       $albumOne->setName('The White Album');
       $albumTwo->setName('Sgt. Pepper');
       $albumOne->setReleaseYear('1974');
       $albumTwo->setReleaseYear('1967');

       $albums = array(
           $albumOne,
           $albumTwo
       );

       $musician->setName('The Beatles');
       $musician->setAlbums($albums);

       $form = $this->getServiceLocator()->get('FormElementManager')->get('MusicianForm');
       $form->setMusician($musician);

       return new ViewModel([

]);

   }
}

当我尝试绑定表单时,我最终得到以下错误:

Zend\Form\Element\Collection::setObject expects an array or Traversable object argument; received "Application\Entity\Musician"

我试图在音乐家类中实现迭代器,但是那里的解决方案似乎很复杂并且不太清楚。如何让这个绑定正常工作?

1 个答案:

答案 0 :(得分:1)

我明白了!

这里的问题是,Zend Framework需要与表单相关的所有实体使其拥有字段集才能使绑定正常工作!

在这个具体示例中,我创建了一个音乐家字段集,将其设置为音乐家表单中的基本字段集,并在音乐家字段集中创建了专辑表单集合。瞧!一切都很好地填充。