Phalconでフォームを利用する

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

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

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

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

app\forms\PostsForm.php

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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に渡す

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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は以下のように組むことができる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<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チェックを行うコードが下のコードになる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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側で展開されることになる。

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

1
2
3
4
5
6
7
8
9
10
namespace Blog\Models;
 
use Phalcon\Mvc\Model;
 
class Posts extends Model {
 
    public function initialize(){
        $this->setSource('posts');
    }
}

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

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

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

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

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