フォームフレームワークの使い方を覚えよう
今回は、第1回で簡単に触れたフォームフレームワークをより詳しく紹介したいと思います。
フォームフレームワークは開発に必須の機能であり、symfony 1.1を使うのであれば、使用方法を覚える必要があります。また新しく覚えることが増えてしまいますが、symfony 1.1を使うのであれば、避けては通れない道です。
第1回では、propel:generate-crudタスクでサンプルとなるスクリプトが生成されることを紹介しただけでしたが、その中身を少し詳しくみていきましょう。まずは、My First Projectチュートリアル(http://www.symfony-project.org/tutorial/1_1/my-first-project)にあるようにpostとcommentテーブルを作成し、frontnedアプリケーションにpost、commentというモジュールを作成しています。
propel:generate-crudで作成したpostモジュールのアクションファイルを見てみると、symfony 1.0とかなり違うことがわかるでしょう。大きな変更点をいくつか以下に挙げます。
1. listアクションの役割がindexアクションになった
2. showアクションが削除された
3. editとcreateアクションがフォームフレームワークを使用して実装されている
4. $requestを引数にとっている
1と2は画面遷移の変更点です。3については以降で詳しく紹介します。ここでは4について簡単に触れたいと思います。symfony 1.1のアクションではリクエストオブジェクトを引数にとることができます。また、バリデーションやエラー処理のメソッドがアクションから廃止されたことによって、常にアクションのpreExecute()メソッドとpostExecute()メソッドが呼ばれるようになったなどの変更点もあります。
それでは、3のeditとcreateアクションの中身について見ていきましょう。フォームフレームワークを使用したアクションの流れは以下のようになります。
1. フォームクラスのインスタンスをテンプレートに割り当て表示する
2. POSTデータをフォームクラスに渡してバリデーションを実行する(bindメソッド)
3. エラーがないかどうかをチェックする(isValidメソッド)
4.1. バリデーションエラーの場合はeditアクションのテンプレートを表示する
4.2. バリデーションで問題がない場合は、リダイレクトする
1がcreate、editアクションで、2以降がupdateアクション内に実装されています。フォームクラスを使用する場合はソースコードは図1のように変える必要があります。
フォームフレームワークを使用したテンプレート
次に、この新しいフォームオブジェクトがテンプレートでどのように使用されるのかを見てみましょう。
テンプレート(templates/editSuccess.php)を見てみると、以前とは完全に異なる書き方をしていることがわかると思います。まずformタグの出力方法からして異なります。
Formヘルパーでの記述方法は以下のようになります。
<?php use_helper('Form') ?>
<?php echo form_tag('post/update') ?>
フォームフレームワークでの記述方法は以下のようになります。
<form action="<?php echo url_for('post/update'.(!$post->isNew() ? 'id='.$post->getId() : '')) ?>" method="post" <?php $form->isMultipart() and print 'enctype="multipart/form-data" ' ?>>
また、デフォルトでバリデーションエラーがテンプレートに表示されるようになりました。例えば、schema.ymlのpostテーブルのtitleカラムにNOT NULLを追加することで、デフォルトのバリデーションに反映されるようになります。
schema.yml
# title: varchar(255)
title: { type: varchar(255), required: true }
上記のようにschema.ymlを書き換えて、以下のコマンドを実行すれば変更がフォームクラスに反映されます。その結果、何も入力しない状態でデータを送信するとエラーが発生するようになります。
$ ./symfony propel:build-model
$ ./symfony propel:build-forms
エラーやタグの出力方法も異なります。Formヘルパーでのエラーの出力方法は以下のようになります。
<?php echo form_error('title') ?>
タグの出力方法は以下のようになります。
<?php echo object_input_tag($post, 'getTitle') ?>
またフォームフレームワークでのエラーの出力方法は以下のようになります。
<?php echo $form['title']->renderError() ?>
同様にタグの出力方法は以下のようになります。
<?php echo $form['title'] ?>
<?php echo $form['title']->render(array('size' => '10')) ?>
フォームフレームワークを使用した場合、$form['title']をechoしていますが、$form['title']は文字列ではなくオブジェクトです。そのため、__toStringマジックメソッドが実行され、その結果が文字列として出力されています。__toStringマジックメソッド内部ではrenderメソッドが呼ばれているので、そのrenderメソッドを呼ぶことも可能で、その場合は属性値を設定することができます。
属性値はrenderメソッドの引数で指定できますが、フォーム要素やバリデーションを操作する場合はどうなるのか、次に見てみましょう。



