我设置了一个基本的概念证明,涉及音乐家和专辑,用于在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"
我试图在音乐家类中实现迭代器,但是那里的解决方案似乎很复杂并且不太清楚。如何让这个绑定正常工作?
答案 0 :(得分:1)
我明白了!
这里的问题是,Zend Framework需要与表单相关的所有实体使其拥有字段集才能使绑定正常工作!
在这个具体示例中,我创建了一个音乐家字段集,将其设置为音乐家表单中的基本字段集,并在音乐家字段集中创建了专辑表单集合。瞧!一切都很好地填充。