There are several different ways to go about Form Creation in Zend Framework 2. This article will focus on extending the Form class and using a form in the ZF2 Skeleton Application.
Assuming you have already created a basic module, you should be ready to start creating a form.
To start with, create a Form/ directory in module/[Your_Module]/src/[Your_Module]. Usually the class name given will be related to the type of form you’re looking to build.
In this example, a simple register form will be built.
The form class must extend Zend\Form\Form and any elements added to the form must be added within the class’ __construct() method.
// module/Siphor/src/Siphor/Form/RegisterForm.php
<?php
namespace Siphor\Form;
use Zend\Form\Form;
class RegisterForm extends Form {
public function __construct($name = 'register')
{
parent::__construct($name);
$this->setAttribute('method', 'post');
}
}
Form elements can be added using the add() method of the Zend\Form\Form class.
// module/Siphor/src/Siphor/Form/RegisterForm.php
<?php
namespace Siphor\Form;
use Zend\Form\Form;
class RegisterForm extends Form {
public function __construct($name = 'register')
{
parent::__construct($name);
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'first_name',
'type' => 'Zend\Form\Element\Text',
'options' => array(
'label' => 'First Name'
),
'attributes' => array(
'type' => 'text',
'required' => true
)
));
$this->add(array(
'name' => 'last_name',
'type' => 'Zend\Form\Element\Text',
'options' => array(
'label' => 'Last Name'
),
'attributes' => array(
'type' => 'text',
'required' => true
)
));
}
}
ZF2 uses its own classes for input types i.e. Zend\Form\Element\Text. There is also a Zend\Form\Element\Email class to use with email inputs.
$this->add(array(
'name' => 'email',
'type' => 'Zend\Form\Element\Email',
'options' => array(
'label' => 'Email Address'
),
'attributes' => array(
'type' => 'email',
'required' => true
)
));
Use the Zend\Form\Element\Password class for password fields. Usually with register forms, a password and a password confirmation field are present.
$this->add(array(
'name' => 'password',
'type' => 'Zend\Form\Element\Password',
'options' => array(
'label' => 'Password'
),
'attributes' => array(
'type' => 'password',
'required' => true
)
));
$this->add(array(
'name' => 'password_verify',
'type' => 'Zend\Form\Element\Password',
'options' => array(
'label' => 'Confirm Password'
),
'attributes' => array(
'type' => 'password',
'required' => true
)
));
Web forms can be susceptible to cross-site request forgery (csrf) attacks. Fortunately, Zend Framework provides us with a Zend\Form\Element\Csrf to use in our forms.
$this->add(array(
'name' => 'csrf',
'type' => 'Zend\Form\Element\Csrf'
));
Lastly, a submit button is required in order for users to be able to submit the form.
$this->add(array(
'name' => 'submit',
'type' => 'Zend\Form\Element\Submit',
'attributes' => array(
'value' => 'Submit'
)
));
The complete form class might look like the following:
// module/Siphor/src/Siphor/Form/RegisterForm.php
<?php
namespace Siphor\Form;
use Zend\Form\Form;
class RegisterForm extends Form {
public function __construct($name = 'register')
{
parent::__construct($name);
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'first_name',
'type' => 'Zend\Form\Element\Text',
'options' => array(
'label' => 'First Name'
),
'attributes' => array(
'type' => 'text',
'required' => true
)
));
$this->add(array(
'name' => 'last_name',
'type' => 'Zend\Form\Element\Text',
'options' => array(
'label' => 'Last Name'
),
'attributes' => array(
'type' => 'text',
'required' => true
)
));
$this->add(array(
'name' => 'email',
'type' => 'Zend\Form\Element\Email',
'options' => array(
'label' => 'Email Address'
),
'attributes' => array(
'type' => 'email',
'required' => true
)
));
$this->add(array(
'name' => 'password',
'type' => 'Zend\Form\Element\Password',
'options' => array(
'label' => 'Password'
),
'attributes' => array(
'type' => 'password',
'required' => true
)
));
$this->add(array(
'name' => 'password_verify',
'type' => 'Zend\Form\Element\Password',
'options' => array(
'label' => 'Confirm Password'
),
'attributes' => array(
'type' => 'password',
'required' => true
)
));
$this->add(array(
'name' => 'csrf',
'type' => 'Zend\Form\Element\Csrf'
));
$this->add(array(
'name' => 'submit',
'type' => 'Zend\Form\Element\Submit',
'attributes' => array(
'value' => 'Submit'
)
));
}
}
Within the IndexController class, import your form class using the ‘use’ keyword.
use Siphor\Form\RegisterForm;
You can then pass the class instance to an array when returning a new ViewModel instance.
// module/Siphor/src/Siphor/Controller/IndexController.php
<?php
namespace Siphor\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Siphor\Form\RegisterForm;
class IndexController extends AbstractActionController
{
public function indexAction()
{
$registerForm = new RegisterForm();
return new ViewModel(array('form' => $registerForm));
}
}
In the view template, the form can be accessed using $this->form as the ‘form’ key was defined in the array when instantiating a new ViewModel class.
To render the form opening and closing tags, the form view helper, $this->form() is used (not to be confused with $this->form).
// module/Siphor/view/siphor/index/index.phtml
<?php
$this->form->setAttribute('class', 'form-horizontal');
$this->form->prepare();
echo $this->form()->openTag($this->form);
echo '<fieldset>';
foreach ($this->form as $element) {
if (!($element instanceof Zend\Form\Element\Submit)) {
?>
<div class="control-group">
<label class="control-label" for="<?php echo $element->getName(); ?>"><?php echo $this->translate($element->getLabel()); ?></label>
<div class="controls">
<?php echo $this->formElement($element); ?>
<?php echo $this->formElementErrors($element); ?>
</div>
</div>
<?php
} else {
$element->setAttribute('class', 'btn btn-primary');
?>
<div class="form-actions">
<?php echo $this->formElement($element); ?>
</div>
<?php
}
}
echo '</fieldset>';
echo $this->form()->closeTag();
When you refresh your application, you should see the form rendered on your designated module’s URL.
Currently the form doesn’t go anywhere, nor does it have any validation. Using the Input Filter will be covered in another post.
Note: This article is based on ZF version 2.4.