前回は Zend Framework 2 でフォームを作成した。このときはコントローラ内でフォームの要素をひとつひとつ追加して作成したが、今回は Form クラスを継承した独自クラスを作ることにする。

いつものとおり、ZendSkeletonModule を改造する。モジュール名、ネームスペースは FormTest2、コントローラ名は Form2Controller とした。

まず、Form クラスを継承した独自クラスを作る。Form クラスを継承した独自クラスのソースコードは、Controller フォルダの同階層に Form フォルダを作り、ここにまとめて置く。今回は以下のファイル名で作成する。
C:\xampp\htdocs\ZendSkeletonApplication\module\FormTest2\src\FormTest2\Form\ContactForm.php
ContactForm.php は以下のとおり。
<?php
namespace FormTest2\Form;
 
use Zend\Captcha\AdapterInterface as CaptchaAdapter;
use Zend\Form\Element;
use Zend\Form\Form;
 
class ContactForm extends Form
{
    protected $captcha;
 
    public function setCaptcha(CaptchaAdapter $captcha)
    {
        $this->captcha = $captcha;
    }
 
    public function prepareElements()
    {
        $this->add(array(
            'name' => 'name',
            'options' => array(
                'label' => 'Your name',
            ),
            'attributes' => array(
                'type'  => 'text',
            ),
        ));
        $this->add(array(
            'type' => 'Zend\Form\Element\Email',
            'name' => 'email',
            'options' => array(
                'label' => 'Your email address',
            ),
        ));
        $this->add(array(
            'name' => 'subject',
            'options' => array(
                'label' => 'Subject',
            ),
            'attributes' => array(
                'type'  => 'text',
            ),
        ));
        $this->add(array(
            'type' => 'Zend\Form\Element\Textarea',
            'name' => 'message',
            'options' => array(
                'label' => 'Message',
            ),
        ));
        $this->add(array(
            'type' => 'Zend\Form\Element\Captcha',
            'name' => 'captcha',
            'options' => array(
                'label' => 'Please verify you are human.',
                'captcha' => $this->captcha,
            ),
        ));
        $this->add(new Element\Csrf('security'));
        $this->add(array(
            'name' => 'send',
            'attributes' => array(
                'type'  => 'submit',
                'value' => 'Submit',
            ),
        ));
    }
}

コントローラ側のソース、Form2Controller.php は以下のようになる。 フォーム作成の細かい処理が ContactForm .php に移ったことで、コントローラのフォーム作成処理はずいぶん簡単になった。
<?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/FormTest2 for the canonical source repository
 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */
 
namespace FormTest2\Controller;
 
use Zend\Mvc\Controller\AbstractActionController;
 
use Zend\Captcha;
use Zend\Form\Element;
use Zend\Form\Form;
 
class Form2Controller extends AbstractActionController
{
    public function indexAction()
    {
        $form = new \FormTest2\Form\ContactForm();
        $form->setCaptcha(new Captcha\Dumb());
        $form->prepareElements();
 
        return array('form' => $form);
    }
 
    public function fooAction()
    {
        $request = $this->getRequest();
        if ($request->isPost()) {
            return array('datas' => $request->getPost());
        }
        return $this->redirect()->toRoute('formtest2');
    }
}

ビュー側のソースは変更不要であるが、index.phtml を以下のように変更してみた。前回よりは幾分シンプルに書ける。
<?php
// within a view script
$form = $this->form;
$form->prepare();
 
// Assuming the "form2/foo" route exists...
$form->setAttribute('action', 'form2/foo');
 
// Set the method attribute for the form
$form->setAttribute('method', 'post');
 
// Render the opening tag
echo $this->form()->openTag($form);
?>
<div class="form_element">
<?php
    $name = $form->get('name');
    echo $this->formRow($name);
?></div>
 
<div class="form_element">
<?php
    $email = $form->get('email');
    echo $this->formRow($email);
?></div>
 
<div class="form_element">
<?php
    $subject = $form->get('subject');
    echo $this->formRow($subject);
?></div>
 
<div class="form_element">
<?php
    $message = $form->get('message');
    echo $this->formRow($message);
?></div>
 
<div class="form_element">
<?php
    $captcha = $form->get('captcha');
    echo $this->formRow($captcha);
?></div>
 
<?php echo $this->formElement($form->get('security')) ?>
<?php echo $this->formElement($form->get('send')) ?>
 
<?php echo $this->form()->closeTag() ?>

続いて foo.phtml のソース。変更していない。
<div>
<strong>datas:</strong>
<?php var_dump($this->datas); ?>
</div>

実行してみる。初期表示。
zendframework2-8

入力後、ボタンを押した状態。
zendframework2-9

以上。