ディスパッチャ
概要
ディスパッチ処理は、リクエストオブジェクトである
Zend_Controller_Request_Abstract を受け取り、
そこに含まれる情報 (モジュール名、コントローラ名、アクション名およびオプションのパラメータ)
を展開し、コントローラのインスタンスを作成してそのコントローラのアクションをコールします。
モジュールやコントローラ、アクションが見つからない場合は、
デフォルト値を使用します。Zend_Controller_Dispatcher_Standard
では、コントローラとアクションのデフォルトはどちらも
index で、モジュールのデフォルトは default です。しかし、
setDefaultController() メソッドや
setDefaultAction() メソッド、そして
setDefaultModule() でこれらを変更することもできます。
デフォルトモジュール
モジュール構造のアプリケーションを作成する場合に、
デフォルトのモジュールにも名前空間を定義したくなることもあるでしょう
(デフォルトの設定では、デフォルトモジュールには名前空間が
ありません)。1.5.0 以降では、
フロントコントローラあるいはディスパッチャで
prefixDefaultModule に TRUE
を設定すればこれが実現できるようになりました。
setParam('prefixDefaultModule', true);
// ディスパッチャで
$dispatcher->setParam('prefixDefaultModule', true);
]]>
これにより、既存のモジュールをアプリケーションのデフォルトモジュールとすることができます。
ディスパッチ処理が発生するのは、フロントコントローラでのループの内部です。
ディスパッチ処理を行う前に、フロントコントローラはルーティングを行い、
ユーザが指定したコントローラとアクション、そして追加のパラメータを取得します。
それからディスパッチループに入り、リクエストを配送します。
ループ内では、まず最初にリクエストオブジェクトのフラグを設定します。
このフラグは、アクションがディスパッチされたことを示すものです。
アクション内や pre/postDispatch プラグインでこのフラグをリセットすると、
ディスパッチループがそのまま継続され、もう一度リクエストを処理しようとします。
リクエスト内のコントローラやアクションを変更してフラグをリセットすることで、
さまざまなリクエストを続けて実行させることができます。
このようなディスパッチ処理を制御する
アクションコントローラのメソッドが _forward() です。
このメソッドを preDispatch()、
postDispatch() やアクションメソッドでコールし、
コントローラやアクション、
そして新しいアクションに送りたい追加のパラメータを指定します。
_forward('bar', null, null, array('baz' => 'bogus'));
}
public function barAction()
{
// 現在のモジュールにある、別のコントローラのアクション
// FooController::bazAction() に転送します
$this->_forward('baz', 'foo', null, array('baz' => 'bogus'));
}
public function bazAction()
{
// 別のモジュールにある、別のコントローラのアクション
// Foo_BarController::bazAction() に転送します
$this->_forward('baz', 'bar', 'foo', array('baz' => 'bogus'));
}
]]>
ディスパッチャのサブクラスの作成
Zend_Controller_Front は、
まず最初にルータをコールして、
リクエスト内で最初にディスパッチできるアクションを決定します。
その後、ディスパッチャループに入り、ディスパッチャをコールしてアクションを振り分けます。
ディスパッチャが動作するためには、さまざまなデータが必要です。
たとえば、コントローラ名やアクション名を決定する方法、
コントローラクラスを探す場所、モジュール名が有効かどうか、
その他、リクエストの内容をディスパッチするために必要な情報を取得する
API が必要となります。
Zend_Controller_Dispatcher_Interface
では次のようなメソッドを定義しています。ディスパッチャは、これを実装しなければなりません。
しかし、たいていの場合は単純に抽象クラス
Zend_Controller_Dispatcher_Abstract
を継承するだけで事足りるでしょう。ここには、これらのメソッドがすでに定義されています。
あるいは、Zend_Controller_Dispatcher_Standard
を継承して、標準の機能と異なる部分だけを変更するということも可能です。
ディスパッチャのサブクラスを作成する必要がある場面としては、
たとえばアクションコントローラ内で
標準とは異なるクラス名やメソッド名の命名規則を使用したいなどということが考えられます。
あるいは、クラスメソッドに振り分けるのではなく
コントローラディレクトリは以下のアクションファイルに振り分けるなど、
異なるディスパッチ方式を使用したい場合にもサブクラスを作成する必要があります。