Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Forms

A form in Laminas is an object. Its class lists the fields, and a view script renders them with ready-made helpers. The controller hands the submitted data to the form and takes it back already processed. The laminas-form package does this; form classes live in module/<Module>/src/Form.

Installation

composer require laminas/laminas-form

The installer offers to inject the Laminas\Form module and a few related ones into config/modules.config.php — accept them all.

The form class

Create the file by hand:

// module/Blog/src/Form/PostForm.php
namespace Blog\Form;
 
use Laminas\Form\Element;
use Laminas\Form\Form;
 
class PostForm extends Form
{
    public function __construct()
    {
        parent::__construct('post');
 
        $this->add([
            'name' => 'title',
            'type' => Element\Text::class,
            'options' => ['label' => 'Title'],
        ]);
 
        $this->add([
            'name' => 'body',
            'type' => Element\Textarea::class,
            'options' => ['label' => 'Text'],
        ]);
 
        $this->add([
            'name' => 'submit',
            'type' => Element\Submit::class,
            'attributes' => ['value' => 'Save'],
        ]);
    }
}

Each add() call adds one field: name is the field name, type the element class, options.label the label and attributes the HTML attributes.

ElementWhat it renders
Element\TextA single-line field
Element\TextareaA multi-line field
Element\Email, Element\PasswordEmail and password fields
Element\SelectA drop-down list
Element\CheckboxA checkbox
Element\SubmitA submit button

Showing the form

The action creates the form and passes it to the view script:

// module/Blog/src/Controller/PostController.php
use Blog\Form\PostForm;
 
public function addAction()
{
    $form = new PostForm();
 
    return new ViewModel(['form' => $form]);
}

The view script renders the form piece by piece:

<!-- module/Blog/view/blog/post/add.phtml -->
<h1>New post</h1>
 
<?php $form = $this->form; ?>
<?php $form->prepare(); ?>
 
<?= $this->form()->openTag($form) ?>
    <?= $this->formRow($form->get('title')) ?>
    <?= $this->formRow($form->get('body')) ?>
    <?= $this->formSubmit($form->get('submit')) ?>
<?= $this->form()->closeTag() ?>

openTag() prints the opening form tag with the POST method, formRow() prints the label, the field and its errors. Open /blog/add — the page shows two fields and a button.

Handling

Extend the action: on submit the form receives the data, validates it and gives it back.

use Blog\Model\Post;
 
public function addAction()
{
    $form = new PostForm();
    $request = $this->getRequest();
 
    if ($request->isPost()) {
        $form->setData($request->getPost());
 
        if ($form->isValid()) {
            $post = new Post();
            $post->exchangeArray($form->getData());
            $this->posts->save($post);
 
            return $this->redirect()->toRoute('blog/view', ['id' => $post->id]);
        }
    }
 
    return new ViewModel(['form' => $form]);
}

Fill in the form and press "Save": the post goes into the posts table and the browser opens its page. While there are no validation rules, isValid() accepts any data — the next lesson adds the rules.

Editing a post

In the edit action the form is first filled with values from the database:

$form->setData(['title' => $post->title, 'body' => $post->body]);

The fields appear with the post's text already in them. On submit the order is the same: setData(), isValid(), getData(), save().

Common mistake

getData() may be called only after isValid(). If you call it earlier, Laminas throws an exception saying the form has not been validated yet. The order is always the same: setData(), then isValid(), then getData().

Thanks for reading!

Donate to the site — we work hard for you.