【问题标题】:Issue with Zend Form hydrator Classmethod not binding properly to object entityZend Form hydrator Classmethod 无法正确绑定到对象实体的问题
【发布时间】:2014-03-18 03:39:18
【问题描述】:

我试图使用 Classmethod() hydrator 将实体 Contact 与默认值(使用 getter)绑定到 ContactForm 表单。

问题是,当我使用一组值调用 setData 时,Hydrator 无法合并默认值和一组值,而是只返回一组值。请在下面找到我的代码摘录。

<?php
// My contact form
namespace Application\Form;

use Zend\Form\Form;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterInterface;

class Contact extends Form
{
    public function __construct($name = 'contact')
    {
        parent::__construct($name);

        $this->add(array(
            'name' => 'name',
            'options' => array(
                'label' => 'Your name',
            ),
            'type'  => 'Text',
        ));
        $this->add(array(
            'name' => 'subject',
            'options' => array(
                'label' => 'Subject',
            ),
            'type'  => 'Text',
        ));
        $this->add(new \Zend\Form\Element\Csrf('security'));
        $this->add(array(
            'name' => 'send',
            'type'  => 'Submit',
            'attributes' => array(
                'value' => 'Submit',
            ),
        ));

        // We could also define the input filter here, or
        // lazy-create it in the getInputFilter() method.
    }


    public function getInputFilter()
    {
        if (!$this->filter) {
            $inputFilter = new InputFilter();
            $inputFilter->add(array('name' => 'name', 'required' => false));
            $inputFilter->add(array('name' => 'subject', 'required' => false));
            $this->filter = $inputFilter;
        }
        return $this->filter;
    }
}

这是我的实体

class Contact
{

    protected $name;
    protected $subject;

    /**
     * @param mixed $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }

    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param mixed $subject
     */
    public function setSubject($subject)
    {
        $this->subject = $subject;
    }

    /**
     * @return mixed
     */
    public function getSubject()
    {
        // Trying to set a default value
        if (null == $this->subject) {
            return 'default subject';
        }
        return $this->subject;
    }

}

这里我在一个控制器动作中测试它

class TestController extends AbstractActionController
{
    public function indexAction()
    {
        $data = array(
            'name' => 'myName'
        );

        $class = '\Application\Entity\Contact';
        $contact = new $class;

        $form = new \Application\Form\Contact();
        $form->setHydrator(new ClassMethods(false));
        $form->bind($contact);
        $form->setData($data);

        if ($form->isValid()) {
            var_dump($form->getData());
        }
        die("end");
    }
}

我想得到

object(Application\Entity\Contact)[---]
    protected 'name' => string 'myName' (length=6)
protected 'subject' => string 'default subject' ...

但是我得到了这个结果

object(Application\Entity\Contact)[---]
  protected 'name' => string 'myName' (length=6)
  protected 'subject' => null

知道如何让 Classmethod() 从绑定中提取 getter 值并合并 setData() 上的剩余数据吗?

【问题讨论】:

    标签: php zend-framework zend-framework2 zend-form zend-form2


    【解决方案1】:

    这实际上很容易设置默认值。 在实体中定义默认值:

    class Contact
    {
       protected $subject = 'Default Subject';
    
      // other properties and methods
    }
    

    此外,还可以在表单中定义默认值:

            $this->add(array(
                'name' => 'subject',
                'options' => array(
                    'label' => 'Subject',
                ),
                'attributes' => array(
                    'value' => 'Default Subject'
                ),
                'type'  => 'Text',
            ));
    

    【讨论】:

    • 感谢您的回复。对于 String 来说似乎没问题,但是 date 数据类型呢? Php 无法将对象初始化为默认值。如果 Hydrator 从它的 getter 中获取变量就好了,对吧?
    • @Nekapps 您可以使用setDate($date = null) 执行此操作,然后如果值为null,则创建一个新的DateTime 实例。或者查看Hydration Strategies 将这些附加到水合器以处理特殊情况。
    • @Nekapps 亚历克斯是对的。要么,通过检查它是否为 null 在 getter 中执行此操作,或者您可以在实体的构造函数中设置默认值!您可以将 classmethods hydrator 扩展为 here
    • @UjjwalOjha 好的...我不知道我上面写的代码是否正确。但是使用 hydrator Classmethodbind 方法不会自动使用实体的 getter 方法。它应该以这种方式工作吗?
    • 我听不懂你想说什么@Nekapps !
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 2016-04-15
    • 1970-01-01
    • 2012-02-27
    相关资源
    最近更新 更多