Phalconでフォームを利用する

namespaceやvalidationを設定しつつフォームを利用してみた

PhalconのフォームはCakePHPのフォームとは異なる

Phalconにもフォームを効率的に組むための仕組みがある。

しかし、CakePHPのform helperと比べると利用の仕方が異なっている。Phalconのフォームでは、フォーム専用のclassを定義して、そのクラスをコントローラから呼び出すという方法を採るのが一般的なようだ。フォームクラスの具体例をあげてみたい。

app\forms\PostsForm.php

として下のフォームを作成する。

namespace Blog\Forms;

use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Textarea;
use Phalcon\Forms\Element\Submit;
use Phalcon\Validation\Validator\PresenceOf;

class PostsForm extends Form
{
    public function initialize($entity = null, $options = null)
    {
	// title
        $title = new Text('title');
        $title->setLabel('Title');
        $title->addValidators(array(
            new PresenceOf(array(
                'message' => 'The title is required'
            ))
        ));
        $this->add($title);

        // body
        $body = new Textarea('body');
        $body->setLabel('Body');
        $body->addValidators(array(
            new PresenceOf(array(
                'message' => 'The body is required'
            ))
        ));
        $this->add($body);
        
	// Post
        $this->add(new Submit('Post', array(
            'class' => 'btn btn-success'
        )));
    }

    public function messages($title)
    {
        if ($this->hasMessagesFor($title)) {
            foreach ($this->getMessagesFor($title) as $message) {
                $this->flash->error($message);
            }
        }
    }
}

上のコードでは、

  • title
  • body

というテキストボックスとテキストエリアを入力するためのフォームを構成している。CakePHPと異なり、冒頭で必要なフォーム部品や設定するvalidationだけをuseすることが可能。上の例では、

PresenceOf

という入力必須項目を設定するためのvalidation機能だけをuseしてある。

このフォームをコントローラから呼び出して利用するので、Phalconにおけるフォームのvalidationはモデル側には設定せずにフォームクラスに定義することになっている。フォームを持たないREST APIでは、モデル側にvalidationを定義することも可能。

Controllerでformを生成しViewに渡す

フォームを定義したのでコントローラからそのフォームを呼び出してみたい。呼び出し部分が以下のコード

namespace Blog\Controllers;

use Blog\Forms\PostsForm;
use Blog\Models\Posts;

class PostController extends ControllerBase
{
    public function addAction()
    {
        $form = new PostsForm();
        $this->view->form = $form;
    }
}

2行に分けて書いてみたが$formを無くして1行で書いても問題はない。2行に分けたのは、その間にPOSTリクエスト(フォームがsubmitされた)の処理を挟むことになるため分けて書いてみた。POSTリクエストの処理を追加する前に、上のコードでView側にフォームの情報が渡されていることを確認したい。Voltテンプレートを利用した場合はViewは以下のように組むことができる。

<div>
	{{ form() }}
		<div>
			<h2>New Post</h2>
		</div>

		<table>
			<tr>
				<td>{{ form.label('title') }}</td>
				<td>
					{{ form.render('title') }}
					{{ form.messages('title') }}
				</td>
			</tr>
			<tr>
				<td>{{ form.label('body') }}</td>
				<td>
					{{ form.render('body') }}
					{{ form.messages('body') }}
				</td>
			</tr>

			<tr>
				<td></td>
				<td>{{ form.render('Post') }}</td>
			</tr>
		</table>
		<hr>
	</form>
</div>

Phalconのフォーム生成プロセスは、

  • フォームクラスでひな形を定義
  • コントローラでフォームを生成
  • Viewで展開

という過程を経て行われる。

Controllerでvalidationチェックを行う

ここまでのコードで定義したフォームをViewに展開することができた。しかし、submitボタンを押してもPOSTリクエストが処理されない状態になっている。コントローラでPOSTリクエストを判定しvalidationチェックを行うコードが下のコードになる。

public function addAction()
{
	$form = new PostsForm();

        // POSTリクエストの判定
        if ($this->request->isPost()) {
            // validationチェック
            if ($form->isValid($this->request->getPost()) != false) {

                // 新規モデルの生成
                $post = new Posts();
                // データの生成
                $post->assign(array(
                    'title' => $this->request->getPost('title'),
                    'body' => $this->request->getPost('body'),
                ));

                // dbへ保存
                if ($post->save()) {
                    return $this->dispatcher->forward(array(
                        'controller' => 'post',
                        'action' => 'index'
                    ));
                }

                $this->flash->error($post->getMessages());
            }
        }
		
	$this->view->form = $form;
}

validationでエラーとなった場合には、

$form

に対してエラー情報が追加され、エラー情報付きのフォームがView側で展開されることになる。

参考として上のサンプルコードで作成したモデルも載せておこうと思う。

namespace Blog\Models;

use Phalcon\Mvc\Model;

class Posts extends Model {

	public function initialize(){
		$this->setSource('posts');
	}
}

フォームクラスにvalidationを定義しているので、モデル側はシンプルになっている。

CakePHPのform helperとはやり方が異なるが、Phalconでも効率的にフォームを組むことができる。

Webエンジニアブログにコメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Phalconでフォームを利用するの記事にコメントを投稿