使用 Zend Framework 在表单中绑定对象时出现问题
Problem with binding an object in the form with Zend Framework
我正在从这个 link 做 Zend Framework 教程:https://docs.zendframework.com/tutorials/getting-started/forms-and-actions/#editing-an-album
我顺利到达这部分,但现在我提出了这个错误:
Argument 1 passed to Zend\Hydrator\ArraySerializableHydrator::extract() must be an instance of Zend\Hydrator\object, instance of Album\Model\Album given, called in /client/zf3/skeleton/vendor/zendframework/zend-form/src/Fieldset.php on line 650
我的代码与教程中的代码相同,我在网上查找了另一个类似的问题,不幸的是我找到了 none。
有没有新的水合器使用方法(与教程相比)?或者我犯了一个我找不到的错误?
module/Album/src/Model/Album.php:
<?php
namespace Album\Model;
use DomainException;
use Zend\Filter\StringTrim;
use Zend\Filter\StripTags;
use Zend\Filter\ToInt;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFIlterInterface;
use Zend\Validator\StringLength;
class Album implements InputFilterAwareInterface{
public $id;
public $artist;
public $title;
private $inputFilter;
public function exchangeArray(array $data){
$this->id = !empty($data['id']) ? $data['id'] : null;
$this->artist = !empty($data['artist']) ? $data['artist'] : null;
$this->title = !empty($data['title']) ? $data['title'] : null;
}
public function getArrayCopy(){
return [
'id' => $this->id,
'artist' => $this->artist,
'title' => $this->title,
];
}
public function setInputFilter(InputFilterInterface $inputFilter){
throw new DomainException(sprintf('%s does not allow injection of an alternate input filter', __CLASS__));
}
public function getInputFilter(){
if($this->inputFilter){
return $this->inputFilter;
}
$inputFilter = new InputFilter();
$inputFilter->add([
'name' =>'id',
'required' => true,
'filters' => [
['name' => ToInt::class],
],
]);
$inputFilter->add([
'name' =>'artist',
'required' => true,
'filters' => [
['name' => StripTags::class],
['name' => StringTrim::class],
],
'validators' => [
[
'name' => StringLength::class,
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
],
],
],
]);
$inputFilter->add([
'name' => 'title',
'required' => true,
'filters' => [
['name' => StripTags::class],
['name' => StringTrim::class],
],
'validators' => [
[
'name' => StringLength::class,
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
],
],
],
]);
$this->inputFilter = $inputFilter;
return $this->inputFilter;
}
}
module/Album/src/Controller/AlbumController.php:
<?php
namespace Album\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Album\Model\AlbumTable;
use Album\Form\AlbumForm;
use Album\Model\Album;
class AlbumController extends AbstractActionController{
private $table;
public function __construct(AlbumTable $table){
$this->table = $table;
}
public function indexAction(){
return new ViewModel([
'albums' => $this->table->fetchAll(),
]);
}
public function addAction(){
$form = new AlbumForm();
$form->get('submit')->setValue('Add');
$request = $this->getRequest();
if(!$request->isPost()){
return ['form' => $form];
}
$album = new Album();
$form->setInputFilter($album->getInputFilter());
$form->setData($request->getPost());
if(! $form->isValid()){
return ['form' => $form];
}
$album->exchangeArray($form->getData());
$this->table->saveAlbum($album);
return $this->redirect()->toRoute('album');
}
public function editAction(){
$id = (int) $this->params()->fromRoute('id',0);
if(0 === $id){
return $this->redirect()->toRoute('album',['action' => 'index']);
}
try{
$album = $this->table->getAlbum($id);
} catch (\Exception $e){
return $this->redirect()->toRoute('album', ['action' => 'index']);
}
var_dump($album);
$form = new AlbumForm();
$form->bind($album);
$form->get('submit')->setAttribute('value','Edit');
$request = $this->getRequest();
$viewData = ['id' => $id, 'form' => $form];
if(! $request->isPost()){
return $viewData;
}
$form->setInputFilter($album->getInputFilter());
$form->setData($request->getPost());
if(! $form->isValid()){
return $viewData;
}
$this->table->saveAlbum($album);
return $this->redirect()->toRoute('album', ['action' => 'index']);
}
public function deleteAction(){
}
}
module/Album/src/Form/AlbumForm.php
<?php
namespace Album\Form;
use Zend\Form\Form;
class AlbumForm extends Form {
public function __construct($name = null){
parent::__construct('album');
$this->add([
'name' => 'id',
'type' => 'hidden',
]);
$this->add([
'name' => 'title',
'type' => 'text',
'options' => [
'label' => 'Title',
],
]);
$this->add([
'name' => 'artist',
'type' => 'text',
'options' => [
'label' => 'Artist',
],
]);
$this->add([
'name' => 'submit',
'type' => 'submit',
'attributes' => [
'value' => 'Go',
'id' => 'submitbutton',
],
]);
}
}
感谢您的帮助!
经过一些研究,我仍然没有找到解决 Hydrator 问题的方法。但是我找到了另一个解决方案,就在这里。
在module/Album/src/Controller/AlbumController.php
public function editAction(){
$id = (int) $this->params()->fromRoute('id',0);
if(0 === $id){
return $this->redirect()->toRoute('album',['action' => 'index']);
}
try{
$album = $this->table->getAlbum($id);
} catch (\Exception $e){
return $this->redirect()->toRoute('album', ['action' => 'index']);
}
$form = new AlbumForm();
$form->setData($album->getArrayCopy());//Here is the change instead of bind
$form->get('submit')->setAttribute('value','Edit');
//Here to save the modifications
$request = $this->getRequest();
$viewData = ['id' => $id, 'form' => $form];
if($request->isPost()){
$form->setData($request->getPost());
if($form->isValid()){
$data = $form->getData();
$album->exchangeArray($data);
$this->table->saveAlbum($album);
return $this->redirect()->toRoute('album', ['action' => 'index']);
}
}
return $viewData;
}
我知道它并不完美,但它比不工作要好。
希望有一天它可以帮助某人。 ;)
我正在从这个 link 做 Zend Framework 教程:https://docs.zendframework.com/tutorials/getting-started/forms-and-actions/#editing-an-album
我顺利到达这部分,但现在我提出了这个错误:
Argument 1 passed to Zend\Hydrator\ArraySerializableHydrator::extract() must be an instance of Zend\Hydrator\object, instance of Album\Model\Album given, called in /client/zf3/skeleton/vendor/zendframework/zend-form/src/Fieldset.php on line 650
我的代码与教程中的代码相同,我在网上查找了另一个类似的问题,不幸的是我找到了 none。
有没有新的水合器使用方法(与教程相比)?或者我犯了一个我找不到的错误?
module/Album/src/Model/Album.php:
<?php
namespace Album\Model;
use DomainException;
use Zend\Filter\StringTrim;
use Zend\Filter\StripTags;
use Zend\Filter\ToInt;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFIlterInterface;
use Zend\Validator\StringLength;
class Album implements InputFilterAwareInterface{
public $id;
public $artist;
public $title;
private $inputFilter;
public function exchangeArray(array $data){
$this->id = !empty($data['id']) ? $data['id'] : null;
$this->artist = !empty($data['artist']) ? $data['artist'] : null;
$this->title = !empty($data['title']) ? $data['title'] : null;
}
public function getArrayCopy(){
return [
'id' => $this->id,
'artist' => $this->artist,
'title' => $this->title,
];
}
public function setInputFilter(InputFilterInterface $inputFilter){
throw new DomainException(sprintf('%s does not allow injection of an alternate input filter', __CLASS__));
}
public function getInputFilter(){
if($this->inputFilter){
return $this->inputFilter;
}
$inputFilter = new InputFilter();
$inputFilter->add([
'name' =>'id',
'required' => true,
'filters' => [
['name' => ToInt::class],
],
]);
$inputFilter->add([
'name' =>'artist',
'required' => true,
'filters' => [
['name' => StripTags::class],
['name' => StringTrim::class],
],
'validators' => [
[
'name' => StringLength::class,
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
],
],
],
]);
$inputFilter->add([
'name' => 'title',
'required' => true,
'filters' => [
['name' => StripTags::class],
['name' => StringTrim::class],
],
'validators' => [
[
'name' => StringLength::class,
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
],
],
],
]);
$this->inputFilter = $inputFilter;
return $this->inputFilter;
}
}
module/Album/src/Controller/AlbumController.php:
<?php
namespace Album\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Album\Model\AlbumTable;
use Album\Form\AlbumForm;
use Album\Model\Album;
class AlbumController extends AbstractActionController{
private $table;
public function __construct(AlbumTable $table){
$this->table = $table;
}
public function indexAction(){
return new ViewModel([
'albums' => $this->table->fetchAll(),
]);
}
public function addAction(){
$form = new AlbumForm();
$form->get('submit')->setValue('Add');
$request = $this->getRequest();
if(!$request->isPost()){
return ['form' => $form];
}
$album = new Album();
$form->setInputFilter($album->getInputFilter());
$form->setData($request->getPost());
if(! $form->isValid()){
return ['form' => $form];
}
$album->exchangeArray($form->getData());
$this->table->saveAlbum($album);
return $this->redirect()->toRoute('album');
}
public function editAction(){
$id = (int) $this->params()->fromRoute('id',0);
if(0 === $id){
return $this->redirect()->toRoute('album',['action' => 'index']);
}
try{
$album = $this->table->getAlbum($id);
} catch (\Exception $e){
return $this->redirect()->toRoute('album', ['action' => 'index']);
}
var_dump($album);
$form = new AlbumForm();
$form->bind($album);
$form->get('submit')->setAttribute('value','Edit');
$request = $this->getRequest();
$viewData = ['id' => $id, 'form' => $form];
if(! $request->isPost()){
return $viewData;
}
$form->setInputFilter($album->getInputFilter());
$form->setData($request->getPost());
if(! $form->isValid()){
return $viewData;
}
$this->table->saveAlbum($album);
return $this->redirect()->toRoute('album', ['action' => 'index']);
}
public function deleteAction(){
}
}
module/Album/src/Form/AlbumForm.php
<?php
namespace Album\Form;
use Zend\Form\Form;
class AlbumForm extends Form {
public function __construct($name = null){
parent::__construct('album');
$this->add([
'name' => 'id',
'type' => 'hidden',
]);
$this->add([
'name' => 'title',
'type' => 'text',
'options' => [
'label' => 'Title',
],
]);
$this->add([
'name' => 'artist',
'type' => 'text',
'options' => [
'label' => 'Artist',
],
]);
$this->add([
'name' => 'submit',
'type' => 'submit',
'attributes' => [
'value' => 'Go',
'id' => 'submitbutton',
],
]);
}
}
感谢您的帮助!
经过一些研究,我仍然没有找到解决 Hydrator 问题的方法。但是我找到了另一个解决方案,就在这里。
在module/Album/src/Controller/AlbumController.php
public function editAction(){
$id = (int) $this->params()->fromRoute('id',0);
if(0 === $id){
return $this->redirect()->toRoute('album',['action' => 'index']);
}
try{
$album = $this->table->getAlbum($id);
} catch (\Exception $e){
return $this->redirect()->toRoute('album', ['action' => 'index']);
}
$form = new AlbumForm();
$form->setData($album->getArrayCopy());//Here is the change instead of bind
$form->get('submit')->setAttribute('value','Edit');
//Here to save the modifications
$request = $this->getRequest();
$viewData = ['id' => $id, 'form' => $form];
if($request->isPost()){
$form->setData($request->getPost());
if($form->isValid()){
$data = $form->getData();
$album->exchangeArray($data);
$this->table->saveAlbum($album);
return $this->redirect()->toRoute('album', ['action' => 'index']);
}
}
return $viewData;
}
我知道它并不完美,但它比不工作要好。 希望有一天它可以帮助某人。 ;)