Self Hydrating Forms in ZF2

Mainly because I keep forgetting how to do this, I decided to create a quick reminder on how to get forms to hydrate into objects when they are successfully validated.

The Form

The form is created in the usual way, however at the top of the __construct() method, add the following:

$this->setHydrator(new Zend\Stdlib\Hydrator\ClassMethods())
        ->setObject(new \My\Custom\Entity());

This tells the form that is should use the ClassMethods hydrator to perform the hydration, and that the object it should hydrate is a new My\Custom\Entity.

The Controller

Presuming that the form is being validated in the usual way, something like:

$form = new MyForm();
if ($this->getRequest()->isPost()) {
    $form->setData($this->getRequest()->getPost());
    if($form->isValid()) {
        $this->myService->save($form->getData());
        $this->redirect('/');
    }
} 
return new ViewModel(array(
    'form' => $form,
));

This assumes that the save method of MyService class (your service layer or data mapper) is expecting an array. However you can get the form to return a hydrated object simply by changing the above code:

$form = new MyForm();
if ($this->getRequest()->isPost()) {
    $form->setData($this->getRequest()->getPost()
    if($form->isValid()) {
        $this->myService->save($form->getObject());
        $this->redirect('/')
    } else {
        $form->bind(new \My\Custom\Entity());
    }
}
return new ViewModel(array(
    'form' => $form,
));

The clever change here is that instead of using $form->getData(), we now use $form->getObject() to return the hydrated entity object. Also notice that if the form fails validation then you have to bind an empty instance of your custom entity to it. I have no idea why you need to do this, I’m presuming (or, indeed, hoping) that some clever clogs will be able to tell me in the comments.

The View

Nothing changes in the view, the only reason I’m mentioning it is because you have to remember to $form->prepare() in the view, or you’ll not get expected results.

2 thoughts on “Self Hydrating Forms in ZF2

  1. Just stumbled upon this, really useful tip, thanks! Going to come in very handy. Don’t know if it was a bug that has been fixed, but I didn’t need to bind the object if validation fails. Seems to work perfectly for me!

  2. Thanks for writing. I could not get my entity automatically hydrated so I had to manually hydrate. If you in that situation then here is how to do this:

    if ( $form->isValid() === false ){
    ….show form
    }

    $hydrator = $form->getHydrator();
    $userEntity = $hydrator->hydrate( $httpRequest->getPost()->toArray(), $userEntity );

Your Comments are Awesome, Please Leave Them!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s