我设置了一个基本的概念证明,涉及音乐家和专辑,用于在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;
}
}
专辑字段集:
专辑字段集:
<?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"
我试图在音乐家类中实现迭代器,但那里的解决方案似乎很复杂,而且不太清楚。如何让此绑定正常工作?
我想通了!
这里的问题是Zend框架要求所有与表单相关的实体都有自己的字段集,以便绑定正常工作!
在此特定示例中,我创建了一个音乐家字段集,将其设置为音乐家窗体中的基本字段集,并在音乐家字段集中创建了专辑窗体集合。瞧!一切都填充得很好。