スポンサーサイト

0

    一定期間更新がないため広告を表示しています


    • 2014.12.23 Tuesday
    • -
    • -
    • -
    • -
    • -
    • by スポンサードリンク

    Symfony Advent Calendar JP day 18 - symfony1 vs Symfony2 フォームを使った検索の書き方比較

    0
      Symfony Advent Calendar JP 2012 18日目です。
      下っ端(むしろ幽霊部員)なのに、ありえない5周目の執筆です(汗
      今回は、symfony1 vs Symfony2 検索フォームの書き方比較と題して、Symfony2用の検索フォームの書き方について書きます。(私のような)symfony1→Symfony2に切り替え真っ最中の方のご参考になればと思います。

      1.検索フォームを表すクラスについて
      symfony1では、Hogeというモデルがある場合、doctrine:build --all-class(もしくは--filtersもしくは--all)によってlib/filter/doctrineに自動生成されるHogeFormFilterというクラスを使用するのが一般的でした。
      HogeFormFilterはsfFormFilterのサブクラスで、通常のフォームを書くときと同様にconfigure(),setup()メソッド内でwidgetとvalidatorをセットすることができ、bind()で入力値を受け取ります。

      一方、Symfony2では検索フォーム専用のフォームクラスというものはありません。
      通常の更新用フォームと同じようにほにゃららTypeクラスを作り、buildForm()で各項目をadd()していきます(もしくはFormBuilderにaddして直でフォームを作る)。
      なお、クラス名に特に決まりがあるわけではないのですが、私が書くときは、Hogeというエンティティがある場合、HogeTypeを登録・更新用、HogeSearchTypeを検索用のようにしています。

      2.csrfトークンチェックを切る
      csrfトークンがついたままだと、何かの検索結果ページをメールやtwitterやredmineでシェアするときに不便ですよね。検索フォームは何かデータの登録・更新・削除を行うフォームではないのでcsrfトークンのチェックは省いても大丈夫だと一般に(?)言われています。
      そこで、symfony1とSymfony2それぞれのやり方で検索フォームのcsrfトークンチェックをOFFにする方法を見てみます。

      symfony1では、HogeFormFilterはsfFormFilterのサブクラス、sfFormFilterはsfFormサブクラスなので、デフォルトの状態ではcsrfトークンチェックが有効になっています。OFFにするには、configure()かsetup()の中で$this->disableLocalCSRFProtection()を呼び出します。(HogeFormFilterをnewするときにコンストラクタの第三引数をfalseにするという方法もあり)

      一方、Symfony2ではsetDefaultOptions()メソッドを定義してcsrf_protectionオプションをfalseにすることにより、csrfトークンのチェックをOFFにできます。
      #HogeSearchType.php

          public function setDefaultOptions(¥Symfony¥Component¥OptionsResolver¥OptionsResolverInterface $resolver)
          {
              $resolver->setDefaults(array(
                  'csrf_protection' => false,
              ));
          }


      3.実際に検索を行う方法
      ここまででフォームHTMLの出力と入力値のバリデーションまでは行えるようになりましたが、いよいよ、実際に入力値による検索を実装する方法が問題となります。

      symfony1では、HogeFormFilter::getQuery()を呼び出すことで、入力値を使った検索用のクエリ(Doctrine_Query)が自動で生成されました。(生成されるクエリ内容をカスタマイズしたい場合はフォームにaddXXXColumnQuery()メソッドを追加することで可能でした)

      これに対し、Symfony2では、検索フォーム自体は登録・更新等に使うのと同じ単なるフォーム生成と入力値の検証のみを担当し、クエリ生成部分はコントローラ側に任されます。(おそらく、symfony1のような実装は、データベースとフォームの結合が密になりすぎて良くないと考えられたのでしょう。)
      getData()によりフォームから取り出した検証済の入力値を使って、コントローラ側で自前で検索クエリを作成するようになっています。
      #コントローラ。$formがnameという項目を持つHogeTypeから作られたフォームとして
      $data = $form->getData(); //array('name' => 'foo')
      $query = $entityManager->getRepository()->createQueryBuilder('r')->where('r.name = :name')->setParameter('name', $data['name'])->getQuery(); //検索用クエリ
      $entities = $query->getResults(); //検索結果

      これだとコントローラの見通しが悪くなり、複数の画面で検索処理を書く場合に不便なため、私はカスタムEntityRepositoryに専用メソッドを追加して実装するようにしています。
      #コントローラ。$formがnameという項目を持つHogeTypeから作られたフォームとして
      $data = $form->getData(); //array('name' => 'foo')
      $query = $entityManager->getRepository('AcmeDemoBundle:Hoge')->generateSearchQuery($data); //検索用クエリ
      $entities = $query->getResult(); //検索結果

      #HogeRepository.php
      public function generateSearchQuery($data)
      {
        $qb = $this->createQueryBuilder('r');
        $qb->where('r.name = :name')->setParameter('name', $data['name']);

        return $qb->getQuery();
      }

      #正直なところ、どっぷりsymfony1脳なせいか、Symfony2の検索実装方法は使いづらいと感じてしまっているのが現状だったり。。。


      スポンサーサイト

      0

        • 2014.12.23 Tuesday
        • -
        • 11:56
        • -
        • -
        • -
        • -
        • by スポンサードリンク

        コメント
        コメントする








           

        PR

        calendar

        S M T W T F S
           1234
        567891011
        12131415161718
        19202122232425
        2627282930  
        << November 2017 >>

        twitter

        selected entries

        categories

        archives

        recent comment

        • 結局CodeIgniter用汎用Modelクラス&汎用CRUDスクリプトを書きました
          プログラマー
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          よし
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          ななうぇぶ
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          よし
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          よし
        • WindowsのPCで開発するphperがxhprofを使う方法
          ななうぇぶ
        • WindowsのPCで開発するphperがxhprofを使う方法
          川本
        • [バッドノウハウ]Symfony2で別テーブルの集計項目を一覧に含めたいとき
          よし
        • Symfony Advent Calendar JP 2012 day 14 - vendorをcomposerで管理しているプロジェクトにcomposerを使わずにバンドルを追加したときのautoloadの書き方
          77web
        • Symfony Advent Calendar JP 2012 day 14 - vendorをcomposerで管理しているプロジェクトにcomposerを使わずにバンドルを追加したときのautoloadの書き方
          ktz

        recent trackback

        • HTMLの表(TABLE)のセル(TD)に斜線を引くjavascriptライブラリ slash.js 作っちゃいました
          常山日記
        • django対symfony 日本語メール送信(その1 symfony編)
          CPA-LABテクニカル
        • CodeIgniterでユーザー認証
          されどLAMPな日々
        • 久々にdjangoを最新版にしたらHTMLがエスケープされちゃった!!(解決済み)
          常山日記
        • FastCGIを諦めてmod_pythonを使う。Apacheのアップグレード
          サーバー用語集
        • さくらインターネット、sqlite3でdjango@CGI版を使う際の設定メモ
          常山日記
        • さくらインターネット スタンダードプランでdjango使ってる方、DBは?
          mitszoの日記
        • python多次元リストをsort(並べ替え)する方法?
          mitszoの日記
        • フォームから送信した値とrequest.POSTの挙動($_POST@PHPとの比較)
          Humming Via Kitchen
        • 日本語テキストをtruncate@django(Python全般にも??)
          常山日記

        recommend

        links

        profile

        search this site.

        others

        mobile

        qrcode

        powered

        無料ブログ作成サービス JUGEM