Symfony2初心者がバンドルを作ってみた

この記事はSymfony Advent Calendar 2011の21日目の記事になります。
Advent Calendarとはなんぞや?という方は下記をどうぞ。

http://gihyo.jp/news/info/2011/12/0101


まず始めに、自分はSymfonyをバージョン1系を使ったことがなく、バージョン2からの初心者です
しかもSymfony2もまだ触り始めて1ヶ月ちょっとになります。
こんな若輩者の私ですので、突っ込みどころがあるかもしれませんので、もし気になるところがありましたら突っ込んでいただければ幸いです。

Symfony2を使ってみて思ったこと

以前までEthnaを使っていたのですが、以前からSymfonyがいいよ!と色々な方から言われていたので触ってみようと思ったところ既にバージョン2が出ている状態だったので、せっかくなので今更バージョン1系を覚えるのもあれかなと思い、バージョン2に的を当ててみました。

Symfony2を触ってみた最初の感想としてはかなり複雑!この一言しか出てきませんでした。
やりたい事の都合上、いきなり触ったのがSecurityコンポーネントだったってのもある気がしますが…
さすがSymfonyは大規模向けで複雑と一般的に言われてるだけあるなぁと言ったのが最初の感想です。

まずはひたすらドキュメントを読み漁るところから始めました。
章によってはドキュメントだけでは足りない部分も多かったですが、そこはGoogle先生を便りに色々読みあさって少しは理解を深めることが出来ました。

ある程度理解が深まった時点での感想はかなり良く出来てるなぁといった感じです。
Symfony2ではDIコンテナとEventDispatcherが採用されており、こいつらのお陰で各々のコンポーネントがほぼ独立していることと自分で作ったコンポーネントを簡単に組み込めるところがすごいです。

もう一点思ったことといえば各々のコンポーネントが独立しすぎていて、素のままのSymfony2では少し入り組んだロジックを組む際には面倒くさいなと思うところもありましたが、ここは先人の方々が色々なバンドルを公開しているので結構カバー出来ました。
後述しますが、自分もSymfony2を勉強していってるうえで、何かバンドルを作ってみようと思い作ってみました。

オレオレバンドルを作ってみた

Symfony2を使って開発していたのですが、情報の登録画面で少し複雑なフォームを作った際に、確認画面を出すときにめんどくさいなぁと思いました。
昔からPHPを触っている身としてはHTML_QuickFormのfreezeみたいなことが出来たら楽だなぁと思い、バンドルを作ってみた次第です。

GitHub - ryster/HaouFormBundle: HaouFormBundle

インストール手順などはREADMEを読んで頂ければと思いますが、機能としては下記の通りです。

  • フォームの凍結機能(HTML_QuickFormのfreezingのようなもの)
  • フォームへのヘルプメッセージ機能


実際のコードを記述していきます。
Formコンポーネントにfreezeオプションを指定するだけでフォームが凍結されます。

<?php
// ...
$form = $this->get('form.factory')->create(new UserType(), new User(), array('freeze' => true));

freezeオプションが指定されたフォームは強制的にフォームタイプがhiddenになります。
現実的に使うとなるとバリデーションが完了した後などにfreezeオプションを指定し直す必要がありますので、下記のようなコードになります。

<?php
    // ...

    /**
     * @Template()
     */
    public function registAction()
    {
        $request = $this->get('request');
        
        $builder = $this->get('form.factory')->createBuilder(new UserType(), new User());
        $form = $builder->getForm();

        // 検証
        if ('POST' === $request->getMethod()) {
            $params = $request->request->get($form->getName());
            $form->bindRequest($request);
            if ($form->isValid()) {
                // 確認画面へ
                if (false == isset($params['_confirmation']) || false == $params['_confirmation']) {
                    // freezeオプションを指定する為に、フォームを生成し直して、bindし直す
                    $form = $builder->setAttribute('freeze', true)->getForm();
                    $form->bindRequest($request)->get('_confirmation')->bind(true);

                    return array('form' => $form->createView());
                }

                // データベースへ保存
                $em = $this->getDoctrine()->getEntityManager();
                $em->persist($form->getData());
                $em->flush();

                return new Response('登録完了');
            }
        }

        return array('form' => $form->createView());
    }

上記のコードで[入力] -> [確認] -> [登録完了]までのページ実装が完了となります。
パーツ毎の凍結も可能です、その際はパーツのFormクラスにfreezeオプションを設定してください。
上記のコードで下記のような画面実装となります。

【入力画面】

【確認画面】


また、フォームのヘルプメッセージを表示したい場合は下記のようにFormBuilderでフォームを生成する際のオプションにexplainを指定してください。

<?php
// ...
$formBuilder->add('name', 'text', array(
    'label'      => '名前',
    'explain'  => '名前は50文字以内で入力してください。')
);

サンプルプログラムの一式をgithubにあげておきますので参考にどうぞ。

https://github.com/ryster/HaouDemoBundle

バンドルを作ってみて思ったこと

簡単なバンドルですが、最初は少し手こずるかなと思っていましたが、実際作った後考えると思ったより案外簡単に作ることができたなといった感じでした。
公開されている他人のバンドルを参考にすると良いです。
自分でバンドルを作ってみると更にSymfony2の理解を深めることができるのでオススメです!
皆さんも便利なバンドルをどんどん作って公開していきましょう!

以上でSymfony Advent Calendar 2011の記事を終わりにします。
明日は@yandoさんの記事になります。