導入 -- このパッケージを使用すると、何がうれしいのか
なぜ "Controller" なの?
このパッケージは、PageController デザインパターンを実装したものです。
これは、リクエストの受け取りと (受け取った GET データあるいは POST
データに依存した) アクションの実行をひとつのページで行うことを意味します。
PageController パターンについては、
Martin Fowler のウェブサイト
および
WACT プロジェクトのウェブサイト
でより詳しく説明されています。
QuickForm においてこれがどのような意味を持つかというと、
ひとつのスクリプト内で、リクエストの内容に応じて
さまざまなフォームの表示や入力内容の検証を行うということです。
これにより、複数ページで構成される複雑なフォーム
(ウィザードなどを思い浮かべでください) を
ほんとうに簡単に作成できるようになります。
PageController パターンの最も基本的な実装は、以下のようになります。
<?php
switch ($_REQUEST['action']) {
case 'foo':
doFoo();
break;
case 'bar':
doBar();
break;
default:
echo 'Hello, world!';
}
?>
|
HTML_QuickForm_Controller はこれより少しだけ複雑で、
3 つの基底クラスが存在します。
リクエストで送信されるアクションは
ページ名とアクション名で構成され、それによって
どのページ (例: 画面表示・フォームの検証など) がリクエストを処理するか・
そのページが何を行うのか
が決まります。
基本的な使用例
セッションの初期化
ページ間でのデータのやりとりの必要がないため、この例ではセッションを使用しません。
しかし、実際に複数ページのフォームを使用する際にはきっとセッションが必要となるでしょう。
HTML_QuickForm_Controller は、セッションを自動的には開始
しません。コントローラクラスのインスタンスを作成する前に、
session_start()
を明示的にコールする必要があります。
このパッケージの機能について理解するため、
HTML_QuickForm チュートリアル
の例を HTML_QuickForm_Controller で書き直してみましょう。
例 47-1基本的なコントローラの使用法
<?php
// コントローラを読み込みます
require_once 'HTML/QuickForm/Controller.php';
// 基底アクションクラスを読み込みます
// (これを継承したクラスをあとで作成します)
require_once 'HTML/QuickForm/Action.php';
// フォームを表すクラス
class FirstPage extends HTML_QuickForm_Page
{
function buildForm()
{
$this->_formBuilt = true;
// フォームに要素を追加します
$this->addElement('header', null, 'QuickForm tutorial example');
$this->addElement('text', 'name', 'Enter your name:', array('size' => 50, 'maxlength' => 255));
// submit ボタンの名前を設定する方法に注意してください
$this->addElement('submit', $this->getButtonName('submit'), 'Send');
// フィルタと検証ルールを追加します
$this->applyFilter('name', 'trim');
$this->addRule('name', 'Please enter your name', 'required', null, 'client');
$this->setDefaultAction('submit');
}
}
// フォームを処理するアクション
class ActionProcess extends HTML_QuickForm_Action
{
function perform(&$page, $actionName)
{
echo '<h1>Hello, ' . htmlspecialchars($page->exportValue('name')) . '!</h1>';
}
}
$page =& new FirstPage('firstForm');
// 'process' ハンドラのみを追加します
// コントローラはこれをデフォルトとして使用します
$page->addAction('process', new ActionProcess());
// コントローラをインスタンス化します
$controller =& new HTML_QuickForm_Controller('tutorial');
// フォーム要素のデフォルト値を設定します
$controller->setDefaults(array(
'name' => 'Joe User'
));
// コントローラにページを追加します
$controller->addPage($page);
// リクエストを処理します
$controller->run();
?>
|
|
もとのコードより冗長になってしまっていると思われるかもしれません。
確かにそのとおりですが、3 ページからなるウィザード形式のフォームを
作成する場合のことを考えてみましょう。HTML_QuickForm_Controller
を使用している場合は、
HTML_QuickForm_Page
のサブクラスを 3 つ作成し、
HTML_QuickForm_Action
に基づいた 'process' イベントのハンドラを作成して
それらをコントローラに追加するだけですみます。
しかし、HTML_QuickForm_Controller を使用していない場合は
大量のプログラミングが必要となることでしょう。
独自のページを作成する
まず
HTML_QuickForm_Page
のサブクラスを作成し、
buildForm()
メソッドをオーバーライドする必要があります。
(QuickForm になじみが深い方なら)
その内容は見慣れているでしょうが、多少の例外があります。
<?php
$this->_formBuilt = true;
?>
|
フォームの作成は "重たい" 処理です。そのため、
本当に必要な場合にのみ
buildForm()
をコールするようにします。この処理を 2 回コールする
(そして要素のセットを 2 回取得する) ことを避けるためには
$_formBuilt プロパティを設定します。
2 番目に注意すべき点は、以下の行です。
<?php
$this->addElement('submit', $this->getButtonName('submit'), 'Send');
?>
|
getButtonName()
メソッドを使用して送信ボタンの名前を指定し、
ボタンがクリックされた際に
'submit'
アクションが実行されるようにしています。
3 番目は、以下の行です。
<?php
$this->setDefaultAction('submit');
?>
|
フォームのボタンをクリックする以外にも、Enter キーを押すことで
フォームを送信することができます。このような場合
ほとんどのブラウザでは特定の送信ボタンが押されたとは考えず、
そのためボタンの名前が送信されません。
setDefaultAction()
で、このような場合にコールされるアクションを
(フォームに特別な hidden フィールドを追加することで)
設定します。
独自のアクションを作成する
通常は、'process' および 'display'
の 2 つのアクションについてのハンドラを作成する必要があります。
前者については、ここで説明することは困難です。というのも、
そのフォームで何をどのように処理すべきなのかを知っているのは
あなた自身だけだからです。後者については、
HTML_QuickForm_Action_Display
のサブクラスを作成してその _renderForm()
メソッドをオーバーライドし、適切な
レンダラ
をコールして独自の出力を行えるようにする必要があります。
すべてをひとつにまとめる
次に、上で定義したページクラスのインスタンスを作成します。
<?php
$page =& new FirstPage('firstForm');
?>
|
そして、そこに独自のアクションハンドラを追加します。
<?php
$page->addAction('process', new ActionProcess());
?>
|
フォームの入力内容が有効だった場合は、
'submit' アクションのデフォルトハンドラとして
'process' アクションがコールされます。
それから、コントローラのインスタンスを作成します。
<?php
$controller =& new HTML_QuickForm_Controller('tutorial');
?>
|
コントローラ名が必須パラメータであることに注意しましょう。
もしアプリケーション内で複数のコントローラを使用するのであれば、
それぞれ別の名前を指定する必要があります。なぜなら、
セッション内に値を保存する際にコントローラ名が使用されるからです。
それから、フォームのデフォルト値を設定してそれをページに追加します。
<?php
$controller->setDefaults(array(
'name' => 'Joe User'
));
$controller->addPage($page);
?>
|
この方法以外にも、
buildForm() の中でページの
setDefaults()
をコールする方法もあります。しかし、前者のアプローチが
すべてのフォームのデフォルト値を一度に指定できるのに対して、
後者の方法では特定のページについてしか設定できません。
最後に、コントローラの
run()
メソッドをコールします。
<?php
$controller->run();
?>
|
これにより、現在のアクション名を取得して適切なハンドラがコールされます。
以上です。
高度な使用例
は、パッケージのアーカイブに含まれています。
上で説明した例と似たものに加えて、
さらに 2 つの複数ページフォームの例が含まれています。
|
HTML_QuickForm_Controller (Previous)
|
(Next) FAQ
|
|
|
Download Documentation
|
Last updated: Sun, 05 Oct 2008 |
|
Do you think that something on this page is wrong? Please file a bug report or add a note.
|
| User Notes: |
Note by: Ed Greenberg
Look in the doc directory under pear...
pear/doc/HTML_QuickForm_Controller/examples/wizard.php
and others
Note by: powtac@gmx.de
Couldn't there be a example with 2 or more quickform pages?
|
|