【问题标题】:Problem with binding an object in the form with Zend Framework使用 Zend Framework 绑定表单中的对象的问题
【发布时间】:2020-02-27 16:36:58
【问题描述】:

我正在通过这个链接做 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

我有与教程中相同的代码,我在互联网上寻找另一个类似的问题,不幸的是我没有找到。

有没有一种新的方式来使用 Hydrator(与教程相比)?还是我犯了一个我找不到的错误?

模块/相册/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;
  }
}

模块/相册/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(){

  }
}

模块/相册/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',
    ],
  ]);
  }
}

感谢您的帮助!

【问题讨论】:

  • 能否请您更具体地提出您的问题。一次将您的问题归结为一个问题很重要。所以。不是对代码进行评分和讨论的论坛,而是针对特定代码问题的论坛。
  • 请加AlbumForm好吗? :)

标签: php zend-framework zend-form


【解决方案1】:

经过一番研究,我仍然没有找到如何解决 Hydrator 的问题。但是我找到了另一个解决方案,就是这样。

在模块/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;
  }

我知道这并不完美,但工作总比不工作好。 希望有一天它可以帮助某人。 ;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2017-05-09
    • 2010-11-22
    • 1970-01-01
    • 2014-03-27
    相关资源
    最近更新 更多